当前位置:   article > 正文

Redis原理及实现细节(2)Redis协议和异步方式_实现 自助机 redis 异步 命令下发

实现 自助机 redis 异步 命令下发

1. Redis的网络层

Reactor【并发】处理连接,线程【串行】处理命令  串行、并发:一个处理器  并行:多个处理器

单Reactor:一个线程同时处理所有连接的数据:【命令】+【网络IO】

(MySQL :一个线程对应一条连接 【并发】处理连接,【并发】处理命令

 

Redis pipeline(客户端的技术)

先把多个请求(request)都发送过去,再按顺序依次处理响应(response)(避免阻塞,提升效率)

send:把request数据写到该连接的fd写缓冲区,协议栈;真正耗时的是服务端处理响应并回复response的recv操作

2.Redis事务

MULTI 开启事务      (MySQL:begin; start transaction;)

EXEC 提交事务       (MySQL:commit;)

DISCARD 取消事务(MySQL:rollback; 之前的命令执行完,再undolog命令逆运算,进行回滚)

WATCH 检测key的变动,若在事务执行中,key变动则取消事务;在事务开启前调用,乐观锁实现(cas);  若被取消则事务返回 nil ;

开启事务后,每个指令都会被放进一个队列中,只有EXEC提交后才开始一次性顺序执行

3.Lua脚本

实现了原子性:redis中加载了一个lua虚拟机;用来执行redis lua脚本;redis lua 脚本的执行是原子性的;当某个脚本正在执行的时候,不会有其他命令或者脚本被执行;lua脚本当中的命令会直接修改数据状态;

redis.conf: lua-time-limit 5000 表示lua脚本执行时长是5s,如果执行了5s还没结束,lua会被kill掉                     

使用

> scripe load ‘local val = KEYS[1]; return val’

lua脚本会把脚本内容字符串通过sha1(对称加密散列函数)生成一个散列值 后面就用这个散列值来代替整个文档

> scripe exists "sha1...."  判断散列值对应的lua脚本是否存在

> scripe flush                   清除所有脚本缓存

> scripe kill                      杀死当前运行的脚本

EVAL script numkeys key [key ...] arg [arg ...]  编译脚本并执行 (测试使用)

EVALSHA sha1 numkeys key [key ...] arg [arg ...]  (线上使用)
(MySQL的lua脚本不具备事务性,显示begin commit; Redis的lua脚本具备原子性 不满足全部ACID)

4. ACID特性

A 原子性:事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;redis不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。
C 一致性:事务使数据库从一个一致性状态到另外一个一致性状态;这里的一致性是指预期的一致性而不是异常后的一致性;所以redis也不满足
I 隔离性:事务的操作不被其他用户操作所打断;redis命令执行是串行的,redis事务天然具备隔离性;(lua脚本实现了完全隔离性  watch可以取消事务实现了隔离性)
D 持久性:redis只有在 aof 持久化策略的时候,并且需要在 redis.conf 中appendfsync=always 才具备持久性;实际项目中几乎不会使用 aof 持久化策略(命令协议的方式进行持久化,一般持久化采用rdb或rdb+aof)


5. Redis发布订阅

多播机制:Redis引入订阅模块PubSub    此外:disque(beta)  一般用:消息队列 zeromq kafka

  • PUBLISH 命令向通道发送信息,此客户端称为publisher 发布者;
  • SUBSCRIBE 向命令通道订阅信息,此客户端称为subscriber 订阅者;
  • 一个发布者向一个通道发送消息,订阅者可以向多个通道订阅消息;当发布者向通道发布消息后,如果有订阅者订阅该通道,订阅者就会收到消息。

subscribe/psubscribe          unsubscribe/punsubscribe                publish                message/pmessage

订阅频道 订阅模式频道      取消订阅频道/取消订阅模式频道      发布内容          客户端收到频道内容/模式频道内容

缺点:

  • 发布订阅的生产者传递过来一个消息,redis会直接找到相应的消费者并传递过去;假如没有消费者,消息直接丢弃;
  • redis停机重启,pubsub的消息是不会持久化的,所有的消息被直接丢弃。

6. 异步连接

连接池:同步连接+线程池

同步连接——阻塞IO   优点:代码书写同步,业务逻辑没割裂  缺点:阻塞直到Redis返回结果,效率低,需要多线程提升效率

异步连接——非阻塞IO   优点:不用阻塞当前线程,用回调函数接收Redis返回值    缺点:代码书写异步,业务逻辑割裂

业务割裂问题:可以用协程来解决(openresty、skynet)

redis6.0以后的io多线程:异步连接池,能更好解决应用层的数据访问性能
主要解决:redis协议的压缩以及解压缩的耗时问题;一般项目中不需要开启;如果有大量并发请求,且返回数据包一般比较大的场景才用


7. Redis协议

协议图:

支持二进制安全字符串

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/550836
推荐阅读
相关标签
  

闽ICP备14008679号