传统的关系型数据库如Mysql已经不能适用所有的场景了,比如秒杀的库存扣减,APP首页的访问流量高峰等等,都很容易把数据库打崩,所以引入了redis。
字符串String,哈希Hash,列表list,无序集合set,有序集合zset
HyperLogLog基数操作,Geospatial地理操作,Bitmaps位操作
如果Key的过期时间设置的过于集中,到达过期时间点是,redis可能会出现短暂的卡顿,严重的化会出现雪崩,我们一般需要在时间上加一个随机值,使得过期时间分散一些。
使用setnx加锁,抢到后使用expire给锁设置过期时间,否则会出现锁忘记释放的现象,同时为了避免拿到锁后进程意外关闭,需要使用set指令将setnx和expire和成一条指令来用。
使用Keys指令扫描出指定模式的Key列表,但是由于redis是单线程的,这个指令会导致线程阻塞,线上服务会停止,知道指令执行完毕,服务才能恢复,为了避免这个现象,我们可以使用scan指令,这个指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,整体所花费的时间也要多一点,同时会存在键在迭代过程中发生了更改,不能保证对返回元素的有效性。
队列的话就是先进先出,可以使用list,使用rpush指令将生产的消息放在列表头,lpop对列表头消息进行消费,当lpop没有消息时,可以使用sleep,一会再试,或者使用blpop,在没有消息的时候进行阻塞。
使用pub/sub主题订阅者模式,可以实现 1:N 的消息队列,在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RocketMQ等。
使用zset,zset会根据score对元素进行排序,将时间戳作为score,消息内容作为Key,来调用zadd生产消息,消费者使用zrangebyscore指令获取之前的数据进行轮训处理。
redis持久化有两种,一种是全量持久化RDB,在达到触发机制设置时,会进行持久化,RDB会耗费较长的时间,在停机时会导致大量数据丢失,所以需要AOF增量持久化来配合使用,AOF会将执行写操作的命令以及结果进行append,如果突然掉电,数据的丢失量需要根据AOF的日志sync属性来决定,如果配置的是每条写指令都sync到磁盘,那就不会丢失,如果是定时sync,则会丢失相应定时时间的数据。
RDB是通过fork和cow来实现的,即通过创建子线程来进行RDB操作,通过写时复制来进行数据页的复制。
可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline 通过减少客户端与 redis 的通信次数来实现降低往返延时时间,而且 Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性。 Pipeline 的默认的同步的个数为53个,也就是说 arges 中累加到53条数据时会把数据提交。
Redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过AOF日志同步即可,有点类似数据库的binlog。