ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## redis与队列 >[info] BLPOP 是列表的阻塞式(blocking)弹出原语。 redis是个对性能要求高的数据存取,特别适合队列,它原生支持并发时串行对数据的存取操作,保证了不会重复取数据,但是它对于储存大量结构化数据,和查询上面不足,毕竟它是nosql,而mysql中规中矩天生关系型数据库,对储存大量数据,和查询select支持得比较好,数据都是持久化的,但是它没有像redis那样原生对并发问题的支持,所以用来做队列实在不明智。所以为了互补,需要结合,redis持久化,和数据查询不好,但是我们又想看到延时队列,延时任务,那么数据存量份就完美解决问题了,redis像往常一样,用来存消息,存消息的同时还往mysql中存一份,队列还跟往常一样,处理消息时,把结果写到mysql那份的状态中,这样就实现了我们的效果,对队列没影响,同时还有记录方便我们查询。 redis的blpop操作是原子性的,原子操作就是不可分割的操作,这个操作有两个动作,取和弹出,数据从队列中取出来,并从队列中删除,这是两步操作,但是由于是原子操作的,所以不可分割,这两步操作就是一个整体不可分割,要么都成功,要么都失败。并且它还是阻塞性的,保证了不会重复取消息。 如果用mysql做这种操作,虽然用锁也可以保证相同的效果,但是太慢了,就没有做队列的价值了,redis数据是在内存中操作,所以很快,即使是单线程阻塞的,也还是很快,快到耗时几乎可以忽略不计,所以用来最队列是最好不过的了。 >[danger] 原子操作是一个整体,不可分割,这个过程是一个整体,别人是不可能插进来的,也就是没有间隙。 * * * * * 多个工人安全的取(不能重复执行,重复取),有锁会阻塞,即使是redis也会阻塞,所以效率低,同一时刻只能有一个工人取,其它的工人,再多也会被阻塞,效率很低,mysql就更低了,如果是错开的方式就不会这样了,工人就可以同时取,还能保证安全,不会重复取,但是这种,对部署等其它方面有要求。不过其实队列任务最耗时的部分是执行部分,取阻塞这点时间,对于任务执行时间来说不算什么,所以工人阻塞也没事,取一下很快的,取了马上就释放了,释放后才开始执行任务,所以这个几乎没什么影响,不是问题。 **比喻:** 1. 两个厨师炒菜,但取菜窗口同时只能有一个人取,假设他们,取菜时间相同,炒菜时间也相同,那么,循环往复,他们只会开始时阻塞一次,此后就不会阻塞。(可以画一个时序图,在时间线上就能够很容易的看出来这些特性) 2. 多个人一起包饺子,但是只有一双筷子用来夹馅儿,那么当一个人在用筷子夹馅儿时,其他人都要等待。 * * * * * ### 根本在于缩短的锁的路径(过程),和量的削峰 > redis也并没有银弹,是的,它也绕不开锁,但是这不影响它解决问题的方式和意义,之所以你觉得它是银弹,可能根本原因在于你没有理解你遇到的问题的根本原因。 redis队列虽然弹出时还是串行的,还是锁,但是它缩短串行的路径,或者说串行的长度、范围,而其它方式锁,锁的路径太长了,锁的是整个执行过程,所以redis方案有意义。 >[danger] **另外如果是多工人进程的话,虽然取是排队串行,但是对于执行时还是会有并发抢占资源问题,还是离不开传统的行锁,所以想只用队列解决并发问题就能高枕无忧一劳永逸是不现实的(没有银弹),除非只有一个工人进程。** 但即使这样队列也有它的意义,起码并发工人进程数量比用户数量少吧(可以理解为用户量是无限的),工人进程还是传统的锁,而少量的工人进程去竞争锁对系统来说几乎没什么压力。**这么来看的话,在这种情况下,redis的作用就是限流和削峰了,其实回到最初的问题,就不难理解这一点了**,最初的问题是mysql(行锁)扛不住高流量、高并发,**只是在大并发时性能下降很快,并不是行锁不行、mysql做不了事**,其根本原因是性能问题,所以我们解决高请求量的问题就行了。 ***** ### 参考 [Redis 实现队列 · php笔记 · 看云](https://www.kancloud.cn/xiak/php-node/399425) [BLPOP — Redis 命令参考](http://redisdoc.com/list/blpop.html) [Redis 实现队列](http://mp.weixin.qq.com/s/Dkz85tZgTs7aPYSJoq4XwA) [高级开发不得不懂的Redis Cluster数据分片机制](https://mp.weixin.qq.com/s/Jm7eg3PHkQwK5gTpksSXQw) [伯克利推出世界最快的KVS数据库Anna:秒杀Redis和Cassandra](http://mp.weixin.qq.com/s/3WmGpZkEuSz-ox_2CPCsqg) > 针对同一个键值的并行更新操作会被串行化,它们需要同步机制来防止多个线程同时更新同一个键值。 [如何保障消息100%成功投递给MQ中间件](https://mp.weixin.qq.com/s/fKTXHvmhdnO_EqBawnBGKQ) [memcache内核,一文搞定!面试再也不怕了!!!(值得收藏)](https://mp.weixin.qq.com/s/zh9fq_e2BgdIeR8RKtY6Sg) [想不到吧?我是这样用Redis实现消息定时推送的!](https://mp.weixin.qq.com/s/ugYV8CBZwbSTs7VkmWy5xg) [一份完整的阿里云 Redis 开发规范,值得收藏](https://mp.weixin.qq.com/s/uKXENaHqfbrIFnbwfJxRNw) [除了缓存,Redis 都解决了哪些问题?](https://mp.weixin.qq.com/s/HUmByMp__slWxoOFdbQCOg) [Memcache & Mysql 常用场景案例](http://blog.sina.com.cn/s/blog_466c66400100i29r.html) [【开源组件】搞懂Redis到底快在哪里](https://mp.weixin.qq.com/s/3EgT5fyaxs-AsfSWi8XG3w) [什么场景应该用 MongoDB ?](https://mp.weixin.qq.com/s/Nw4ZcJUH2vH-SQDY5wPVPg) [微信高并发资金交易系统设计方案——百亿红包背后的技术支撑](https://mp.weixin.qq.com/s/suBAJrP6uN2kFgHtGz16mw) > 任何大规模的东西都是模块化的,手机就是个例子,手机的功能没有局限性是因为可以安装各种软件,这些软件就相当于手机的一个模块。 > sql ,redis 命令,函数,语句,等等,你写的那些都不是真正起作用的地方,都不是实际做操作的地方,都是一些命令发送,系统调用而已,执行 redis 命令只是将命令从客户端发送给redis服务端而已,是否真正执行,何时执行,如何执行,都是由接收命令的服务端决定的,函数调用也是如此,写代码的地方都不是真正起作用做事的地方,真正处理的地方是底层的操作系统,而如何处理接收到的系统调用是操作系统决定的。在任何地方工作,都需要遵守它的规则才能更好的完成任务,编码就是这样,遵循服务端软件的规则,了解操作系统底层的一些原理,将对你编码有很大帮助,能让你从底层去理解函数执行的细节,从而彻底掌控你写的代码。 [优雅实现延时任务之Redis篇](https://mp.weixin.qq.com/s/MjOq3qO9tqxhHX7W0v6ZPw) [Redis进阶不得不了解的内存优化细节](https://mp.weixin.qq.com/s/8dFB-ksyfn7nZ6HGeV56Aw) [关系型数据库 VS NoSQL,谁才是王者](https://mp.weixin.qq.com/s/PIVpNFPZn2go7rDhh-7pLQ) [InfluxDB - 简书]([https://www.jianshu.com/p/68c471bf5533](https://www.jianshu.com/p/68c471bf5533)) > InfluxDB(时序数据库),常用的一种使用场景:监控数据统计。每毫秒记录一下电脑内存的使用情况,然后就可以根据统计的数据,利用图形化界面(InfluxDB V1一般配合Grafana)制作内存使用情况的折线图; [「ThinkPHP开发者周刊」第26期——Redis](https://www.kancloud.cn/thinkphp/weekly/content/26.md) [Reids之神奇的HyperLoglog解决统计问题](https://mp.weixin.qq.com/s/8FyBfqZClBNJ4wqGxkcuIA) [Redis之发布/订阅与Stream](https://mp.weixin.qq.com/s/awYFIP-grggXZkzlbrbulA) [为什么 Redis 默认 16 个库?90% 以上程序员不知道!](https://mp.weixin.qq.com/s/_jFxvy6sit24oooSf55q2g) [不支持原子性的 Redis 事务也叫事务吗? - 不假 - 博客园](https://www.cnblogs.com/lazyegg/p/13625275.html) > Redis 事务可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,**按顺序地串行化执行而不会被其它命令插入,不许加塞。** [图解|什么是高并发利器NoSQL](https://mp.weixin.qq.com/s/ZxY97aHVKSEXiNywx3OYkg) [你真的知道怎么实现一个延迟队列吗 ?](https://mp.weixin.qq.com/s/DcyXPGxXFYcXCQJII1INpg) [简单理解 Kafka 的消息可靠性策略](https://mp.weixin.qq.com/s/T6gCc8OBgyV-yeAg_MUzPQ) > 没有任何人能为你保证可靠,业务方自己能确认任务完成才是最可靠的,毕竟自己说可靠才算是可靠。 [WeCron是怎样处理定时任务的](https://blog.betacat.io/post/how-wecron-schedules/) [Why Disaster Happens at the Edges: An Introduction to Queue Theory – The New Stack 为什么灾难发生在边缘: 排队论导论](https://thenewstack.io/an-introduction-to-queue-theory-why-disaster-happens-at-the-edges/) ---- last update:2018-3-11 10:25:01