草庐IT

amazon-web-services - 当多个客户端尝试同时读/写一个项目时,Redis 是原子的吗?

coder 2023-07-18 原文

假设我有几个构成我的 API 的 AWS Lambda 函数。其中一个函数从单个 Redis 节点上的特定键读取特定值。业务逻辑如下:

if the key exists:
    serve the value of that key to the client
if the key does not exist:
    get the most recent item from dynamoDB
    insert that item as the value for that key, and set an expiration time
    delete that item from dynamoDB, so that it only gets read into memory once
    Serve the value of that key to the client

这个想法是每次客户端发出请求时,他们都会获得所需的值。如果 key 已经过期,那么 lambda 需要先从数据库中获取该项目并将其放回 Redis。

但是如果 2 个客户端同时对 lambda 进行 API 调用会怎样?两个 lambda 进程是否会读取没有 key ,并且都将从数据库中获取一个项目?

我的目标是实现一个队列,其中某个项目仅在内存中保留 X 时间,一旦该项目过期,就应该从数据库中提取下一个项目,并且在提取时应该也被删除,这样它就不会被再次拉动。

我正在尝试看看是否有一种方法可以做到这一点,而无需单独的 EC2 进程来跟踪时间。

redis+lambda+dynamoDB 是否适合我要实现的目标,或者是否有更好的方法?

最佳答案

Redis 服务器将以原子方式执行命令(或事务或脚本)。但是涉及单独服务(例如 Redis 和 DynamoDB)的一系列操作将不是原子的。

一种方法是通过在您的业务逻辑周围添加某种锁来使它们成为原子。这可以是 done with Redis ,例如。

但是,这是一个成本高昂且相当麻烦的解决方案,因此如果可能的话,最好将您的业务逻辑简单地设计为在面对并发操作时具有弹性。为此,您必须查看这些步骤并想象如果多个客户端同时运行会发生什么情况。

在您的情况下,我看到的缺陷是可以从 DynamoDB 读取和删除两个值,一个在 Redis 中覆盖另一个。这可以通过使用 Redis 的 SETNX 来避免。 (SET if Not eXists)命令。像这样:

GET the key from Redis
If the value exists:
    Serve the value to the client
If the value does not exist:
    Get the most recent item from DynamoDB
    Insert that item into Redis with SETNX
        If the key already exists, go back to step 1
    Set an expiration time with EXPIRE
    Delete that item from DynamoDB
    Serve the value to the client

关于amazon-web-services - 当多个客户端尝试同时读/写一个项目时,Redis 是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52079560/

有关amazon-web-services - 当多个客户端尝试同时读/写一个项目时,Redis 是原子的吗?的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  6. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  7. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  8. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  9. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  10. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

随机推荐