浅谈Redis(二)
文章目录
Redis分布式锁
Redis分布式锁有多种实现方式。
- 想要实现分布式锁,必须要求Redis有互斥的能力,我们可以使用set命令。
# nx表示没有就设置并返回True,否则不设置并返回False
# px表示过期时间用毫秒级
set key_name value nx px 30000
- 使用Redission框架可以方便的实现。
RLock lock = redisson.getLock("myLock");
# 加锁和释放锁
lock.lock();
lock.unlock();
Redis集群
一、主从模式
- 主从复制数据库分为主数据库master和从数据库slave。主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库。从数据库一般都是只读的,并且接收主数据库同步过来的数据。一个master可以有多个slave,但一个slave只能对应一个master。slave挂了不影响其他slave的度和master的读写,重启后会将数据从master同步过来。master挂了后不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务。master挂了后,不会在slave节点中重新选一个master。
- 工作机制是当slave启动后,主动向master发送sync命令。master接收到sync命令后台保存快照和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。复制初始化后,master每次收到的写命令都会同步发送给slave,保证主从数据一致性。
二、Sentinel哨兵模式
-
Sentinel模式是建立在主从复制的基础上的,如果只有一个Redis节点,哨兵也就没有意义了。当master挂了以后,哨兵会在slave中选择一个作为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master。当master重启后,它将不再是master而是作为slave接受新的master的同步数据。哨兵进程有挂掉的可能,可以做集群,多个哨兵之间也会自动监控。当主从模式配置密码时,哨兵会同步将配置信息修改到配置文件中,不需要担心。一个哨兵或哨兵集群可以管理多个主从Redis,多个哨兵也可以监控同一个Redis。哨兵和Redis尽量不要部署在同一台机器。
-
哨兵的工作原理是每个哨兵以1s/次的频率向它所知的master、slave以及其他哨兵实例发送一个ping命令。如果一个实例距离最后一次有效回复ping命令的时间超过down-after-milliseconds选项指定的值,则这个实例会被哨兵标记为主观下线。如果一个master被标记为主观下线,则正在监视这个master的所有哨兵要以1s/次的频率确认master的确进入了主观下线状态。当有足够数量的哨兵在指定的时间范围内确认master的确进入了主观下线的状态,则master会标记为客观下线。一般情况下,每个哨兵会以10s/次的频率向它所知的master、slave发送info命令。当master被哨兵标记为客观下线时,哨兵向下线的master的所有slave发送info命令的频率会从10s/次改为1s/次。如果没有足够数量的哨兵同意master已经下线,master的客观下线转态会被移除,如果master重新向哨兵发送ping命令并返回有效回复,master的主观下线状态就会被移除。
-
当采用哨兵模式时,客户端不需要直接连接Redis,而是连接哨兵的IP和port,由哨兵来提供具体的可提供服务的Redis实现,这样当master节点挂掉后,哨兵就会感知并将新的master节点提供给使用者。
三、cluster
- 哨兵模式基本满足了一般生产的需求并且具备高可用性,但是当数据量过大到一台服务器存放不下的情况时,主从模式或哨兵模式就不能满足需求了。cluster模式的出现是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。
- cluster模式可以实现主从和master重选功能,如果配置两个副本三个分片,就需要6个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。使用集群只需要将Redis配置文件中的cluster-enable配置打开即可。每个集群总至少需要三个主数据库才能正常运行,新增节点非常方便。
- 多个Redis节点网络互连,彼此数据共享。所有的接地那都是一主一从或一主多从,其中从数据库不提供服务,作为备用。不支持同时处理多个key,因为redis需要把key均匀分布在各个节点上,并发量很高时同时创建key-value会降低性能。客户端可以连接任何一个主节点进行读写,可以在线增加和删除节点。
Redis同步机制
-
全同步指slave启动时进行的初始化同步。slave启动时,向master发送一个sync命令。master收到指令后会启动一个备份进程把所有数据写入到RDB文件中。更新master的状态,然后把RDB文件内容发送给等待中的slave。
-
部分同步是Redis运行过程中的修改同步。当Redis的主从服务启动后,首先进行全同步。然后把所有的写操作都在master上,读操作都在slave上。master收到一个操作判断是否需要同步到slave,如果需要同步则将操作记录到AOF文件中,遍历所有的slave,把操作的指令和参数写入到slave的恢复缓存中,一旦slave对应的socket发送缓存中有空间写入数据,就把数据通过socket发送出去。
Redis与数据库的双写一致性
- 先淘汰缓存,再写数据库,休眠1s后再次淘汰缓存。
Redis如果有大量Key需要设置同一时间过期要怎么做
- 如果大量的key的过期时间过于集中,到过期的那个时间点,Redis可能出现短暂的卡顿现象,严重情况下可能出现缓存雪崩,我们需要在时间上加一个随机值,使得过期时间分散。
Redis事务
- Redis会把一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务执行过程中插入执行另一个客户端发出的请求,这样能保证Redis将这些命令作为一个单独的隔离操作执行。在一个Redis事务中,Redis要么执行其中的所有命令,要么什么都不执行。因此Redis事务能够保证原子性。
- Redis是支持原子性的,只能保证串行执行命令,并且能保证全部执行,但是执行命令失败时并不会回滚,而是继续执行下去。
- Redis事务不支持事务回滚机制。Redis使用事务队列来预先将执行命令存储起来,并进行格式检查,提前就知道命令是否可以执行了。所以如果只要有一个命令是错误的,那么这个事务是不能执行的,所以Redis事务不支持检查那些程序员自己逻辑错误。
Redis数据结构及其使用场景
Redis本身是一个Map类型的存储方式,所有的数据都是采用的key:value形式存储。Redis的数据类型的key部分都是字符串。
一、string
-
string是Redis的最基本的数据类型,存储单个数据,一个key对应一个value。
-
string可以用作缓存,比如把常用信息、字符串、图片或者视频等信息放到Redis中,Redis做缓存层,MySQL做持久化层,降低MySQL的读写压力。作为计数器,进行访问量统计。共享用户的Session。
二、hash
- hash字典适合存储对象,类似Map的一种结构,可以将结构化的数据缓存到Redis中,然后每次读写缓存的时候就可以操作hash中的字段,底层使用哈希表机构实现数据存储。
- hash可以用来存储对象信息,比如电商网站购物车,把用户id作为键,不同的商品id作为属性,购买数量作为属性值。
三、list
- list有序列表可以存储多个数据并对数据进入存储空间的顺序进行区分,底层使用双向链表存储结构实现。
- list可以用来实现消息队列,朋友圈点赞要求按照点赞顺序显示点赞好友信息。
四、set
- set无序集合会自动去重,有交集、差集、并集等操作,能够保存大量数据,是高效的内部存储机制,便于查询,尤其是随机查询。
- set可以用于全局去重,随机推荐类信息检索,比如热点歌单推荐、热点新闻推荐、热点旅游线路等。
五、zset
- zset有序集合是排序的set,去重并且可以排序,写入数据时会赋予一个分数,自动根据分数排序。有序集合可以用于一些排序场景。底层采用跳跃表实现。
- zset可以实现排行榜应用,延迟任务,范围查找。