我是 Redis 的新手,正在阅读 Redis in Action 一书,该书详细介绍了竞争条件和不同的锁定机制以避免它。(有一个专门的章节)。 但是在一些 StackOverflow 帖子中讨论了 Redis 是单线程的。 链接如下: Are redis operations on data structures thread safe
在上面的链接中(在其中一个答案中)明确写道,当命令正在执行时,不会运行其他命令。
现在我的问题是:如果 Redis 是单线程的,那么为什么还需要锁定机制。
请澄清一下,如果我的理解有任何错误,请告诉我。
同时它遵循乐观锁机制,多个线程可能尝试更新数据,如果数据被修改,它会通知其他尝试同时更新的线程(因为他们更新失败,他们可以再次重试相同的)操作)。
最佳答案
If Redis is Single Threaded, then why need Locking mechanism at all.
Redis 确实(大部分)是单线程的,但当多个客户端尝试在相邻的时间邻近处做不同的事情时,需要锁定。 RiA 中讨论的锁定正是关于这一点 - 确保只有一个客户端/线程执行特定任务,或者确保更新不会出错。
下面是一个示例,说明为什么尽管 Redis 是单线程的,您仍需要锁定:假设您在 Redis 中有一个值,例如存储在名为 foo 的键下的一个数字。您的应用代码读取该数字 (GET foo),对其执行一些操作(例如加 1)并将其写回 (SET)。当您在单线程中运行代码时,它看起来是这样的:
App Redis
|---- GET foo ---->|
|<------ 1 --------|
| |
| thinking... |
| |
|--- SET foo 2 --->|
|<----- OK --------|
现在让我们看看当两个应用客户端尝试这样做时会发生什么:
App 1 Redis App 2
|---- GET foo ---->| |
|<------ 1 --------|<--- GET foo -----|
| |------- 1 ------->|
| thinking... | |
| | thinking...|
|--- SET foo 2 --->| |
|<----- OK --------|<--- SET foo 2 ---|
| |------ OK ------->|
在这里你可以立即看到没有锁定发生了什么,尽管服务器(大部分)是单线程的 - 而不是 3,foo 的值是 2。当你添加更多线程/客户端/应用程序时,当多个编写者试图在没有协调的情况下(例如锁定)修改数据时,事情可能会变得令人愉快和可怕的错误。
乐观锁定只是其中一种方法,Redis 通过 WATCH 机制提供内置功能。然而,有时,乐观主义——尽管其随和和快乐的本性——并不是正确的解决方案,因此您需要实现更好/先进/不同的机制来防止竞争条件。可以说,这样的锁甚至可以在 Redis 外部实现,但如果您已经在使用它,那么在其中管理您的锁也是有意义的。
关于Redis:竞争条件和单线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30004364/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS
除了可访问性标准不鼓励使用这一事实指向当前页面的链接,我应该怎么做重构以下View代码?#navigation%ul.tabbed-ifcurrent_page?(new_profile_path)%li{:class=>"current_page_item"}=link_tot("new_profile"),new_profile_path-else%li=link_tot("new_profile"),new_profile_path-ifcurrent_page?(profiles_path)%li{:class=>"current_page_item"}=link_tot("p
我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我