赞
踩
Reactor【并发】处理连接,线程【串行】处理命令 (串行、并发:一个处理器 并行:多个处理器)
单Reactor:一个线程同时处理所有连接的数据:【命令】+【网络IO】
(MySQL :一个线程对应一条连接 【并发】处理连接,【并发】处理命令)
Redis pipeline(客户端的技术)
先把多个请求(request)都发送过去,再按顺序依次处理响应(response)(避免阻塞,提升效率)
send:把request数据写到该连接的fd写缓冲区,协议栈;真正耗时的是服务端处理响应并回复response的recv操作
MULTI 开启事务 (MySQL:begin; start transaction;)
EXEC 提交事务 (MySQL:commit;)
DISCARD 取消事务(MySQL:rollback; 之前的命令执行完,再undolog命令逆运算,进行回滚)
WATCH 检测key的变动,若在事务执行中,key变动则取消事务;在事务开启前调用,乐观锁实现(cas); 若被取消则事务返回 nil ;
开启事务后,每个指令都会被放进一个队列中,只有EXEC提交后才开始一次性顺序执行
实现了原子性: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)
A 原子性:事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;redis不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。
C 一致性:事务使数据库从一个一致性状态到另外一个一致性状态;这里的一致性是指预期的一致性而不是异常后的一致性;所以redis也不满足;
I 隔离性:事务的操作不被其他用户操作所打断;redis命令执行是串行的,redis事务天然具备隔离性;(lua脚本实现了完全隔离性 watch可以取消事务实现了隔离性)
D 持久性:redis只有在 aof 持久化策略的时候,并且需要在 redis.conf 中appendfsync=always 才具备持久性;实际项目中几乎不会使用 aof 持久化策略(命令协议的方式进行持久化,一般持久化采用rdb或rdb+aof)
多播机制:Redis引入订阅模块PubSub 此外:disque(beta) 一般用:消息队列 zeromq kafka
subscribe/psubscribe unsubscribe/punsubscribe publish message/pmessage
订阅频道 订阅模式频道 取消订阅频道/取消订阅模式频道 发布内容 客户端收到频道内容/模式频道内容
缺点:
连接池:同步连接+线程池
同步连接——阻塞IO 优点:代码书写同步,业务逻辑没割裂 缺点:阻塞直到Redis返回结果,效率低,需要多线程提升效率
异步连接——非阻塞IO 优点:不用阻塞当前线程,用回调函数接收Redis返回值 缺点:代码书写异步,业务逻辑割裂
业务割裂问题:可以用协程来解决(openresty、skynet)
redis6.0以后的io多线程:异步连接池,能更好解决应用层的数据访问性能
主要解决:redis协议的压缩以及解压缩的耗时问题;一般项目中不需要开启;如果有大量并发请求,且返回数据包一般比较大的场景才用
协议图:
支持二进制安全字符串
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。