Hello,redis!我们相处已经很多年了,从模糊的认识到现在我们已经深入结合,你的好我一直都知道也一直都记住,能否再让我多问你的几个问题,让我更加深入的去了解你 。
文章插图
图片来自包图网
Redis 的通讯协议是什么
文章插图
Redis 的通讯协议是文本协议,是的,Redis 服务器与客户端通过 RESP(Redis Serialization Protocol)协议通信 。
没错,文本协议确实是会浪费流量,不过它的优点在于直观,非常的简单,解析性能极其的好,我们不需要一个特殊的 Redis 客户端仅靠 Telnet 或者是文本流就可以跟 Redis 进行通讯 。
客户端的命令格式:
- 简单字符串 Simple Strings,以 "+"加号开头 。
- 错误 Errors,以"-"减号开头 。
- 整数型 Integer,以 ":" 冒号开头 。
- 大字符串类型 Bulk Strings,以 "$"美元符号开头 。
- 数组类型 Arrays,以 "*"星号开头 。
文章插图
简单总结:具体可以见
https://redis.io/topics/protocol,Redis 文档认为简单的实现,快速的解析,直观理解是采用 RESP 文本协议最重要的地方,有可能文本协议会造成一定量的流量浪费,但却在性能上和操作上快速简单,这中间也是一个权衡和协调的过程 。
Redis 究竟有没有 ACID 事务
文章插图
要弄清楚 Redis 有没有事务,其实很简单,上 Rredis 的官网查看文档,发现:
文章插图
Redis 确实是有事务,不过按照传统的事务定义 ACID 来看,Redis 是不是都具备了 ACID 的特性 。
ACID 指的是:
- 原子性
- 一致性
- 隔离性
- 持久性
原子性
事务具备原子性指的是,数据库将事务中多个操作当作一个整体来执行,服务要么执行事务中所有的操作,要么一个操作也不会执行 。
①事务队列
首先弄清楚 Redis 开始事务 multi 命令后,Redis 会为这个事务生成一个队列,每次操作的命令都会按照顺序插入到这个队列中 。
这个队列里面的命令不会被马上执行,直到 exec 命令提交事务,所有队列里面的命令会被一次性,并且排他的进行执行 。
文章插图
对应如下图:
文章插图
从上面的例子可以看出,当执行一个成功的事务,事务里面的命令都是按照队列里面顺序的并且排他的执行 。
但原子性又一个特点就是要么全部成功,要么全部失败,也就是我们传统 DB 里面说的回滚 。
当我们执行一个失败的事务:
文章插图
可以发现,就算中间出现了失败,set abc x 这个操作也已经被执行了,并没有进行回滚,从严格的意义上来说 Redis 并不具备原子性 。
②为何 Redis 不支持回滚
这个其实跟 Redis 的定位和设计有关系,先看看为何我们的 MySQL 可以支持回滚,这个还是跟写 Log 有关系,Redis 是完成操作之后才会进行 AOF 日志记录,AOF 日志的定位只是记录操作的指令记录 。
而 MySQL 有完善的 Redolog,并且是在事务进行 Commit 之前就会写完成 Redolog,Binlog:
文章插图
要知道 MySQL 为了能进行回滚是花了不少的代价,Redis 应用的场景更多是对抗高并发具备高性能,所以 Redis 选择更简单,更快速无回滚的方式处理事务也是符合场景 。
一致性
事务具备一致性指的是,如果数据库在执行事务之前是一致的,那么在事务执行之后,无论事务是否成功,数据库也应该是一致的 。
从 Redis 来说可以从 2 个层面看,一个是执行错误是否有确保一致性,另一个是宕机时,Redis 是否有确保一致性的机制 。
①执行错误是否有确保一致性
推荐阅读
- 面试问Redis集群,被虐的不行了
- 光动能是西铁城好还是卡西欧好?我有话要说
- 咖啡入门常识及意式咖啡豆分享
- 前5个基于Redis的Java对象
- 一款免费的Redis桌面客户端:RediNav
- Redis 图形化工具
- 瞬间几千次的重复提交,我用Spring Boot+Redis扛住了
- Redis如何清除过期key? 一篇文章带你走近源码!
- Centos7 搭建LTMP环境PHP、Tengine、Mysql、Supervisord、Redis
- Redis内存分析工具--rdr安装与使用