加入收藏 | 设为首页 | 会员中心 | 我要投稿 武汉站长网 (https://www.027zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

redis系列(二)redis协议与异步方式

发布时间:2022-10-31 15:30:59 所属栏目:PHP教程 来源:网络
导读: redis网络模型
redis是基于reactor模式设计的内存数据库。
使用reactor模型的好处:
redis是单线程
redis 单线程是指其网络事件处理模型 reactor 是单线程,即指令的执行是在单线程上操作。

redis网络模型

redis是基于reactor模式设计的内存数据库。

使用reactor模型的好处:

redis是单线程

redis 单线程是指其网络事件处理模型 reactor 是单线程,即指令的执行是在单线程上操作。但是其包括IO读取,网络IO操作都是通过多线程执行的。

单线程的优点:

redis pipeline

redis pipeline 是一个客户端提供的机制,指将多个命令同时发送给redis服务端.

例如多个连续的incr指令,使用pipeline(管道)后,多个连续的incr指令会被统一写到发送缓冲区,只会花费一次网络来回开销,这个开销会随着n数值的增大,大幅减少网络io开销,从而提升整体服务的性能。

但是当发送缓冲区或者接收缓冲区满了的话,也会导致阻塞。导致客户端负载过重,整个请求时间变长。所以在使用pipeline时需要注意发送指令的大小。

在这里插入图片描述

redis事务

事务:用户定义一系列数据库操作,这些操作视为一个完整的逻辑处理工作单元php单线程,要么全部执行,要么全部不执行,是不可分割的工作单元。

事务提供了一种将多个命令打包,然后一次性有序(FIFO)执行的机制

事务相关指令 功能RedisMysql

开启事务

MULTI

begin / start transaction

提交事务

EXEC

commit

取消事务

DISCARD

rollback

监听

WATCH

watch是redis独有的其功能是检测 key 的变动,若在事务执行中,key 变动则取消事务;需要在事务开启前调用,乐观锁实现(cas);若被取消则事务返回 nil;

例如:

在这里插入图片描述

可以从例子看出上述事务逻辑是乐观锁实现,失败需要重试,增加特务逻辑的复杂度。

悲观锁在执行时,会将其他处理数据库的请求拦截,使其他请求等待。

乐观锁在执行时,不会将数据锁住,让其他数据库请求等待。

监听机制原理:

监控机制触发:所有对数据库进行修改的命令,如SET、LPUSH、SADD、ZREM、DEL、FLUSHDB等,在执行之后都会调用multi.c/touchWatchKey函数对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的key,有的话touchWatchKey函数会将监视的客户端的REDIS_DIRTY_CAS标识打开,表示该客户端事物安全性已经被破坏。

判断事物是否安全 :当服务器接收到一个客户端发来的EXEC命令时,服务器将会根据这个客户端是否打开REDIS_DIRTY_CAS标识来决定是否执行事物。

在实际工程应用中一般不会用到上述的事务操作。更多的使用脚本执行,例如lua 脚本。在了解lua脚本之前先熟悉一下ACID特性。

ACID特性分析

A 原子性;事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;redis 不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直到将事务队列中的所有命令都执行完毕为止。

C 一致性;事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测;这里的一致性是指预期的一致性而不是异常后的一致性;所以 redis 也不满足;这个争议很大:redis 能确保事务执行前后的数据的完整约束;但是并不满足业务功能上的一致性;比如转账功能,一个扣钱一个加钱;可能出现扣钱执行错误,加钱执行正确,那么最终还是会加钱成功;系统凭空多了钱;

I 隔离性;各个事务之间互相影响的程度;redis 是单线程执行,天然具备隔离性;

D 持久性;redis 只有在 aof 持久化策略的时候,并且需要在 redis.conf 中 appendfsync=always 才具备持久性;实际项目中几乎不会使用 aof 持久化策略;

redis天然只满足一致性和隔离性。原子性和持久性不满足。

lua脚本

lua脚本具备原子性;不具备一致性,出现错误不会回滚。同样满足隔离性;持久性不满足。

lua 脚本实现原子性;

redis 中加载了一个 lua 虚拟机;用来执行 redis lua 脚本;redis lua 脚本的执行是原子性的;当某个脚本正在执行的时候,不会有其他命令或者脚本被执行;

lua 脚本当中的命令会直接修改数据状态;

lua 脚本 mysql 存储区别:MySQL存储过程不具备事务性,所以也不具备原子性;

注意:如果项目中使用了 lua 脚本,不需要使用上面的事务命令;

 测试使用
EVAL script numkeys key [key ...] arg [arg ...]
# 线上使用
EVALSHA sha1 numkeys key [key ...] arg [arg ...]

项目使用先通过script load将lua脚本生成一个40位的字符串(sha1的哈希算法)然后通过evalsha执行脚本

redis异步连接

同步连接方案采用阻塞 io 来实现;优点是代码书写是同步的,业务逻辑没有割裂;缺点是阻塞当前线程,直至 redis 返回结果;通常用多个线程来实现线程池来解决效率问题;

异步连接方案采用非阻塞 io 来实现;优点是没有阻塞当前线程,redis 没有返回,依然可以往 redis 发送命令;缺点是代码书写是异步的(回调函数),业务逻辑割裂,可以通过协程解决(openresty,skynet);配合 redis6.0 以后的 io 多线程(前提是有大量并发请求),异步连接池,能更好解决应用层的数据访问性能;

在这里插入图片描述

hiredis 提供异步连接方式,提供可以替换 IO 检测的接口;

关键替换 addRead, delRead , addWrite, delWrite, cleanup, scheduleTimer,这几个检测接口;其他 io 操作,比如 connect, read, write, close等都交由 hiredis 来处理;

同时需要提供连接建立成功以及断开连接的回调;

用户可以使用当前项目的网络框架来替换相应的操作;从而实现跟项目网络层兼容的异步连接方案;

(编辑:武汉站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!