Reids的特点
Redis本质上是一个Key-Value类型的内存数据库,因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB
Redis支持的数据类型
Strings Lists Sets 求交集、并集 Sorted Set hashes
Redis分布式锁
先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。如果在setnx之后执行expire之前进程意外crash或者要重启维护了,这个锁就永远得不到释放了。set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!
假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,全部找出来
使用keys指令可以扫出指定模式的key列表,因为redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
Redis做异步队列
一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。不使用sleep的话使用blpop。对于一次生产多次消费使用pub/sub主题订阅者模式,可以实现1:N的消息队列。但在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
大量的key尽量不要设置同一个过期时间
到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。
Redis持久化
bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件重新构建内存,再使用aof重放近期的操作指令来实现完整恢复重启之前的状态。bgsave原理: fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
Pipeline作用
可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。
Redis同步机制
主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。这是一个典型的分布式读写分离模型。我们可以利用master来插入数据,slave提供检索服务。这样可以有效减少单个机器的并发访问数量
Redis集群
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。
Redis单线程
单线程避免多线程模式下切换和竞争产生的消耗,它的非阻塞IO采用了epoll实现了多路复用,避免网络IO浪费时间。IO多路复用是这样的,所有访问redis的客户端请求,最后都是对应到Redis服务端的Socket上,IO多路复用则是由一个Reactor的文件处理器,他会去监听这些Socket的文件描述符FD(因为linux万物皆文件)当 accept、read、write 和 close 文件事件产生时,文件事件处理器就会回调 FD 绑定的事件处理器。也就是执行客户端的命令,所以即便是单线程,也能解决多个网络IO请求,而且由于基于内存的查询很快,基本没有阻塞,引入多线程的话就得介入锁和线程的切换,会消耗系统资源。
虚拟内存
当你的key很小而value很大时,使用VM的效果会比较好.因为这样节约的内存比较大.
Redis利用淘汰策略实现内存中的数据都是热点数据
挑选最近最少使用的数据淘汰 挑选将要过期的数据淘汰 任意选择数据淘汰 等等