资讯专栏INFORMATION COLUMN

单线程的redis如何实现并发访问?

keithxiaoy / 2079人阅读

摘要:单线程程序绝对可以通过使用复用机制和事件循环用的是事件循环在级别上提供并发性。操作是原子的事实仅仅是单线程事件循环的结果。如果是单线程的那么为什么需要锁定机制呢确实大多是单线程但当多个客户端尝试在相邻的时间接近时进行不同的事情时则需要锁定。

在服务器端软件中, 并发和并行性通常被认为是不同的概念。在服务器中, 支持并发 i/o 意味着服务器能够通过执行与那些客户端仅有一个计算单元对应的几个流来为多个客户端提供服务。在这种情况下, 并行性意味着服务器能够同时执行多个操作 (具有多个计算单元), 这是不同的。

例如, 一个酒保可以照顾几个客户, 而他只能准备一次饮料。这样他就可以不并行地提供并发性。

单线程程序绝对可以通过使用 i/o 复用机制和事件循环 (Redis用的是事件循环), 在 i/o 级别上提供并发性。

并行性具有成本: 在现代硬件上可以找到多个套接字/多个内核, 线程之间的同步非常昂贵。另一方面, 像 Redis 这样的高效存储引擎的瓶颈往往是网络--CPU前面的陷阱。因此, 孤立的事件循环 (不需要同步) 被视为构建高效、可伸缩的服务器的良好设计。

Redis 操作是原子的事实仅仅是单线程事件循环的结果。有趣的一点是, 原子性是以不额外的成本提供的 (它不需要同步)。用户可以利用它来实现乐观锁定和其他模式, 而无需支付同步开销。

如果 Redis 是单线程的, 那么为什么需要锁定机制呢?

Redis 确实 (大多是) 单线程, 但当多个客户端尝试在相邻的时间接近时进行不同的事情时, 则需要锁定。在 RiA 中讨论的锁定完全是关于-确保只有一个客户端/线程执行特定任务, 或者确保更新不会出错。

这里有一个例子, 为什么你需要锁定, 尽管 Redis 有单线程性: 假设你有一个值在 Redis, 一个数字, 例如存储在一个名为 foo 的键值下。您的应用程序的代码读取该数字 (GET foo), 做一些事情 (ADD 1) 并将其写回 (SET)。当您在单个线程中运行代码时, 这就是它的外观:

应用程序 Redis

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 通过监视机制提供内置。然而, 有时, 乐观-尽管看上去容易且快乐-通常不是正确的解决方案, 所以你需要实施更好/先进/不同的机制, 以防止竞态条件。可以说, 这样的锁可能在 Redis 之外实现, 但如果您已经使用它, 那么在其中管理您的锁也是有意义的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/36511.html

相关文章

  • redis简介及常见问题

    摘要:是单线程,从而避开了多线程中上下文频繁切换的操作。既然单线程容易实现,而且不会成为瓶颈,那就顺理成章地采用单线程的方案了毕竟采用多线程会有很多麻烦。 [toc] 简介 redis全称:Remote Dictionary Server。 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据fl...

    klivitamJ 评论0 收藏0
  • redis使用中存在问题及如何避免(一)

    摘要:给我们带来便利的同时,使用过程中会存在什么问题呢,本文将简单加以总结。避免使用内存过大的实例。如果主线程距离上一次的成功超过,为了数据安全会阻塞直到后台线程执行完完成。 redis可以满足很多的应用场景,而且因为将所有数据都放到内存中,所以它的读写性能很好,很多公司都在使用redis。redis给我们带来便利的同时,使用过程中会存在什么问题呢,本文将简单加以总结。 阻塞问题 r...

    jackzou 评论0 收藏0
  • redis使用中存在问题及如何避免(一)

    摘要:给我们带来便利的同时,使用过程中会存在什么问题呢,本文将简单加以总结。避免使用内存过大的实例。如果主线程距离上一次的成功超过,为了数据安全会阻塞直到后台线程执行完完成。 redis可以满足很多的应用场景,而且因为将所有数据都放到内存中,所以它的读写性能很好,很多公司都在使用redis。redis给我们带来便利的同时,使用过程中会存在什么问题呢,本文将简单加以总结。 阻塞问题 r...

    ralap 评论0 收藏0
  • 七道常见Redis面试题分享

    摘要:综合上述缺点,小明痛定思痛,提出了经营方式二。当客户下单,小明按送达地点标注好,依次放在一个地方。因此,有强一致性要求的数据,不能放缓存。迅速判断出,请求所携带的是否合法有效。 showImg(https://segmentfault.com/img/bVbvHHL?w=1341&h=448); 绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和...

    zhiwei 评论0 收藏0
  • 分布式之redis复习精讲

    摘要:引言为什么写这篇文章博主的分布式之消息队列复习精讲得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。单线程的为什么这么快分析这个问题其实是对内部机制的一个考察。 引言 为什么写这篇文章? 博主的《分布式之消息队列复习精讲》得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。但是还是要说明一下,复习精讲的文章偏面试准备,真正在开发过程中,还是脚踏实地,一步一个脚...

    cooxer 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<