## 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
- 开始
- 公益
- 更好的使用看云
- 推荐书单
- 优秀资源整理
- 技术文章写作规范
- SublimeText - 编码利器
- PSR-0/PSR-4命名标准
- php的多进程实验分析
- 高级PHP
- 进程
- 信号
- 事件
- IO模型
- 同步、异步
- socket
- Swoole
- PHP扩展
- Composer
- easyswoole
- php多线程
- 守护程序
- 文件锁
- s-socket
- aphp
- 队列&并发
- 队列
- 讲个故事
- 如何最大效率的问题
- 访问式的web服务(一)
- 访问式的web服务(二)
- 请求
- 浏览器访问阻塞问题
- Swoole
- 你必须理解的计算机核心概念 - 码农翻身
- CPU阿甘 - 码农翻身
- 异步通知,那我要怎么通知你啊?
- 实时操作系统
- 深入实时 Linux
- Redis 实现队列
- redis与队列
- 定时-时钟-阻塞
- 计算机的生命
- 多进程/多线程
- 进程通信
- 拜占庭将军问题深入探讨
- JAVA CAS原理深度分析
- 队列的思考
- 走进并发的世界
- 锁
- 事务笔记
- 并发问题带来的后果
- 为什么说乐观锁是安全的
- 内存锁与内存事务 - 刘小兵2014
- 加锁还是不加锁,这是一个问题 - 码农翻身
- 编程世界的那把锁 - 码农翻身
- 如何保证万无一失
- 传统事务与柔性事务
- 大白话搞懂什么是同步/异步/阻塞/非阻塞
- redis实现锁
- 浅谈mysql事务
- PHP异常
- php错误
- 文件加载
- 路由与伪静态
- URL模式之分析
- 字符串处理
- 正则表达式
- 数组合并与+
- 文件上传
- 常用验证与过滤
- 记录
- 趣图
- foreach需要注意的问题
- Discuz!笔记
- 程序设计思维
- 抽象与具体
- 配置
- 关于如何学习的思考
- 编程思维
- 谈编程
- 如何安全的修改对象
- 临时
- 临时笔记
- 透过问题看本质
- 程序后门
- 边界检查
- session
- 安全
- 王垠
- 第三方数据接口
- 验证码问题
- 还是少不了虚拟机
- 程序员如何谈恋爱
- 程序员为什么要一直改BUG,为什么不能一次性把代码写好?
- 碎碎念
- 算法
- 实用代码
- 相对私密与绝对私密
- 学习目标
- 随记
- 编程小知识
- foo
- 落盘
- URL编码的思考
- 字符编码
- Elasticsearch
- TCP-IP协议
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依赖注入
- 开发笔记
- 经纬度格式转换
- php时区问题
- 解决本地开发时调用远程AIP跨域问题
- 后期静态绑定
- 谈tp的跳转提示页面
- 无限分类问题
- 生成微缩图
- MVC名词
- MVC架构
- 也许模块不是唯一的答案
- 哈希算法
- 开发后台
- 软件设计架构
- mysql表字段设计
- 上传表如何设计
- 二开心得
- awesomes-tables
- 安全的代码部署
- 微信开发笔记
- 账户授权相关
- 小程序获取是否关注其公众号
- 支付相关
- 提交订单
- 微信支付笔记
- 支付接口笔记
- 支付中心开发
- 下单与支付
- 支付流程设计
- 订单与支付设计
- 敏感操作验证
- 排序设计
- 代码的运行环境
- 搜索关键字的显示处理
- 接口异步更新ip信息
- 图片处理
- 项目搭建
- 阅读文档的新方式
- mysql_insert_id并发问题思考
- 行锁注意事项
- 细节注意
- 如何处理用户的输入
- 不可见的字符
- 抽奖
- 时间处理
- 应用开发实战
- python 学习记录
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文档相似度验证
- thinkphp5.0数据库与模型的研究
- workerman进程管理
- workerman网络分析
- java学习记录
- docker
- 笔记
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京东
- pc_detailpage_wareBusiness
- doc
- 电商网站设计
- iwebshop
- 商品规格分析
- 商品属性分析
- tpshop
- 商品规格分析
- 商品属性分析
- 电商表设计
- 设计记录
- 优惠券
- 生成唯一订单号
- 购物车技术
- 分类与类型
- 微信登录与绑定
- 京东到家库存系统架构设计
- crmeb
- 命名规范
- Nginx https配置
- 关于人工智能
- 从人的思考方式到二叉树
- 架构
- 今日有感
- 文章保存
- 安全背后: 浏览器是如何校验证书的
- 避不开的分布式事务
- devops自动化运维、部署、测试的最后一公里 —— ApiFox 云时代的接口管理工具
- 找到自己今生要做的事
- 自动化生活
- 开源与浆果
- Apifox: API 接口自动化测试指南