说到NOSQL,不得不得说一下redis,它是一种支持Key-Value等多种数据结构的存储系统,可用于缓存,事件发布或订阅,高速队列等场景。该数据库使用ANSI C语言编写,支持网络,提供字符串,哈希,集合结构直接存取,基于内存,也可持久化,因为这些特性,我们在项目中经常使用,下面从以下几个方面做一个小的总结。
- redis特性
- 过期策略&淘汰机制
- 数据持久化
- 集群策略
- 与其它NOSQL产品对比
- 缓存使用常见问题&应对策略
redis特性
- 内存数据库,速度快,也支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- 支持master多slave模式的数据备份,集群去中心化,去中间件,每个主节点平等。
- 支持事务 & MQ。
- 单线程模型,避免了频繁的上下文切换,另外采用了非阻塞I/O多路复用机制,单线程管理多个IO流。
- 支持多种数据类型,String、Hash、Set、SortedSet等。
过期策略&淘汰机制
对于数据管理,redis采用的是定期删除+惰性删除策略,为什么采用这些样的策略管理方式呢,因为定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,我们应该保证业务正常运作,而不是删除key,因此采用了定时删除和惰性删除策略。所谓定时删除,一般默认100毫秒检测一次,每次检查只是随机抽样,而惰性删除,当获取某个key的时候,则先检查key是否设置了过期时间,如果过期了此时就会删除。
以上策略,确实是缓减了对CPU的占用,尽可能保证业务正常运作,但存一个问题,因为定时删除不一定能清除掉数据,同时,如果对于某些KEY用户很长一段时间没有访问,也可能会造成内存占用越来越多,为了解决这个问题,redis 还供了其它配置来回收内存,就是在redis.conf配置文件可以找到“# maxmemory-policy volatile-lru”,来配制相关机制:
- noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,推荐使用。
- allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,一般不推荐使用。
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用,一般不推荐。
- volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key,依然不推荐。
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除,不推荐。
数据持久化
redis提供了不同级别的持久化方式,一种是RDB,另一种是AOF,可以同时开启两种持久化方式,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
- RDB:在指定的时间间隔能对数据进行快照存储(隔一段时间,把内存里的数据转存在硬盘里的文件)。
- AOF:每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
集群策略
-
主从复制
数据库分为俩类,主数据库(master)和从数据库(slave),其中主从复制有如下特点:
- 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
- 从数据库一般都是只读的,并且接收主数据库同步过来的数据
- 一个master可以拥有多个slave,但是一个slave只能对应一个master
主从复制工作原理见:https://www.jianshu.com/p/9445a977adf3
主从存在的问题
redis主从模式解决了数据备份和单例可能存在的性能问题,但是其也引入了新的问题。主从模式下可以将读写操作分配给不同的实例进行从而达到提高系统吞吐量的目的,但也正是因为这种方式造成了使用上的不便,因为每个客户端连接redis实例的时候都是指定了ip和端口号的,如果所连接的redis实例因为故障下线了,而主从模式也没有提供一定的手段通知客户端另外可连接的客户端地址,因而需要手动更改客户端配置重新连接。另外,主从模式下,如果主节点由于故障下线了,那么从节点因为没有主节点而同步中断,因而需要人工进行故障转移工作。
-
sentinel模式
为解决主从模式存在的问题,引入sentinel模式,也就是哨兵模式,哨兵的作用就是对Redis的系统的运行情况的监控,它是一个独立进程,它的作用主要是:
- 监控主数据库和从数据库是否运行正常;
- 主数据出现故障后自动将从数据库转化为主数据库;
sentine模式原理

从图中可以看出,对于一组主从节点,sentinel只是在其外部额外添加的一组用于监控作用的redis实例。在主从节点和sentinel节点集合配置好之后,sentinel节点之间会相互发送消息,以检测其余sentinel节点是否正常工作,并且sentinel节点也会向主从节点发送消息,以检测监控的主从节点是否正常工作。sentinel架构的主要作用是解决主从模式下主节点的故障转移工作的。这里如果主节点因为故障下线,那么某个sentinel节点发送检测消息给主节点时,如果在指定时间内收不到回复,那么该sentinel就会主观的判断该主节点已经下线,那么其会发送消息给其余的sentinel节点,询问其是否“认为”该主节点已下线,其余的sentinel收到消息后也会发送检测消息给主节点,如果其认为该主节点已经下线,那么其会回复向其询问的sentinel节点,告知其也认为主节点已经下线,当该sentinel节点最先收到超过指定数目(配置文件中配置的数目和当前sentinel节点集合数的一半,这里两个数目的较大值)的sentinel节点回复说当前主节点已下线,那么其就会对主节点进行故障转移工作,故障转移的基本思路是在从节点中选取某个从节点向其发送slaveof no one(假设选取的从节点为127.0.0.1:6380),使其称为独立的节点(也就是新的主节点),然后sentinel向其余的从节点发送slaveof 127.0.0.1 6380命令使它们重新成为新的主节点的从节点。重新分配之后sentinel节点集合还会继续监控已经下线的主节点(假设为127.0.0.1:6379),如果其重新上线,那么sentinel会向其发送slaveof命令,使其成为新的主机点的从节点,如此故障转移工作完成。
-
cluster模式
网友评论