Remote Dictionary Server 远程字典服务,是一个开源的、支持网络、可基于内存也可以持久化的日志型、Key-Value数据库。可以用作数据库、缓存和消息中间件(消息队列)。
redis为了保证效率,数据都是缓存在内存中。效率高,可作为其他数据库,如MySQL的缓存。
持久化:redis会周期性的把更新的数据写入磁盘(RDB),或者把修改操作写入追加的记录文件(AOF),并且在此基础上实现了master-slave(主从)同步。
性能
reids是基于内存操作的,cpu不是redis的性能瓶颈,而是内存和带宽。所以redis是单线程的。
为什么单线程还那么快?
redis所有的数据存储在内存中,不存在I/O阻塞和调度的情况,也就不需要多个线程提高并发,多线程反而会导致CPU调度的额外消耗。
redis使用了I/O多路复用技术,能够使用单线程同时处理多个连接。
string字符串
最常用的类型,可以用set, get, append, strlen进行字符串操作。
getrange 截取字符串 setex 创建有寿命的项 setnx 不存在再创建
redis可以识别整型数字,可以进行整型数操作, 如incr命令 +1, decr -1, incrby +n , decrby -n 等。
hash散列
哈希表,结构是 key-<key, value>,即string格式中的value变成了一个哈希表
list列表
底层实现是双向链表,实现各种线性表的操作
set集合
无序的集合,底层实现是哈希表
sorted set(Zset)有序集合
在定义的时候要给每一个记录添加一个score值,用来排序。score值需要是合法的float值。
bitmap位图
位存储,用于高效率存储双状态量。
hyperloglog
用于基数统计,即统计不重复的元素数量,譬如网站的访问人数。
理论上set也能用,但hyperloglog占用内存小。每个 HyperLogLog 键只需要花费 12KB 内存,就可以计算接近 2^64 个不同元素的基数。
因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。也因此 HyperLogLog 会存在少量的误差,约为0.81%。
geospatial 地理位置
用于定位,包括经度、纬度、名称等属性,可以计算地点的距离、指定半径内的其他地点等。经纬度数据是float格式,有效的经度是-180~180,纬度是-85~85。
底层实现是用Zset,可以用Zset命令来操作geo。
一组命令的集合/队列。
redis的单条命令是原子性的,但是事务不保证原子性!
redis事务没有隔离级别!
事务异常处理
编译异常:如果事务代码有语法错误,会抛出异常,事务取消
运行时异常:如果事务中存在数据性错误(如访问一个空值),则其他命令正常执行,错误命令抛出异常。所以没有原子性!
乐观锁
redis 用版本号机制实现乐观锁。
在事务之前使用watch语句监视修改值,watch语句获取对应值的版本号。如果事务提交之前有其他线程修改了对应值,则使本事务失败。
失败后如果要再次执行事务,应先用unwatch先解锁再加锁。
redis是内存数据库,如果不持久化,数据断电即失。
RDB(Redis Database)
以指定的时间间隔将内存中的数据快照写入磁盘文件(默认dump.rdb)。恢复时直接将redis目录下的快照文件读入内存。
redis会单独创建一个子进程来进行持久化,会先将数据写入一个临时文件,等到持久化过程结束,再用临时文件代替之前的的数据库快照文件。
过程中主进程无须进行I/O操作,所以RDB效率较高,适合大规模的数据恢复。
缺点是如果最后一次持久化出错,则会出现一段时间的数据丢失,所以适用于数据完整性要求不高的情景。
AOF(Append Only File)
将所有的写操作追加记录在日志文件中,redis启动时会读取日志文件进行数据库重构。
可以控制追加日志文件的频率,如每次操作都追加,或者每隔几秒追加。
显然,效率较低,且日志文件远大于RDB。但是数据完整性好。
发布和订阅
redis发布订阅是一种消息通信模式,发布者发送消息,订阅者接收消息。
redis客户端可以订阅任意数量的频道。和kafka类似,但采用的是服务器推送模式。
默认情况下,redis每一台服务器都是主节点 master,从节点 slave 需要手动配置。每一个主节点可以有多台从节点。
所有的写操作都由主节点完成,从节点负责从主节点处备份数据,以及处理读操作。在读多写少的情况下,可以实现负载均衡。
配合哨兵模式,可以在主节点宕机之后,选择一个从节点晋升为主节点。如果没有哨兵,则 slave 需要等待 master 恢复
全量复制:slave 会将接收到的数据全部存盘并加载进内存
增量复制:master 将修改命令依次发给 slave,完成同步
每次主节点和从节点进行连接或恢复,都会进行全量复制。
一般情况下,如果主节点宕机,需要手动配置新的主节点,费时费力,还会造成一段时间服务不可用。哨兵是redis的独立进程,可以检测节点的可用性。如果主节点宕机,则选举出新的主节点。
哨兵通过发送命令,让服务器回应其运行状态,包括 master 和 slave。当哨兵检测到 master 宕机,会通过投票的方式选出一个 slave 成为新的 master ,然后通过发布订阅模式告知其他 slave,修改配置文件,切换 master。
单哨兵的可靠性依旧不够,可以配置多个哨兵,哨兵之间也会进行监控。
过程
假设 master 宕机,哨兵检测到这个结果,会将其标记为“主观下线”。
当其他哨兵也检测到宕机,并且数量达到一定值时,哨兵会发起投票。投票的目标写在配置文件中。
进行故障转移failover操作,切换 master。
通过发布订阅模式告知其他 slave,称为“客观下线”。
优点:主从配置模式提高可用性,实现负载均衡。自动切换主从,健壮性提高。
缺点:配置复杂,不易扩容
评论区