1.Redis的数据类型及应用场景
数据类型:5中基本数据类型和3种特殊数据类型
String类型 :key value的存储简单的数据,可以用来失效简单Redis分布式锁。list类型 :是一个列表的数据类型,按照插入顺序排序看,可重复。l表示头部插入,r代表尾部插入数据。set类型 :set是一个无序不重复的集合。可以用来用来统计点赞和收藏的数据量。hash类型 :类似于java的pojo模型,key相当于this对象,field是对象属性名,value是对象对应的属性值。zset :有序不重复的集合。可以用里面的score来做排行榜。Geospatial :底层是zset类型,用来放地址位置的坐标。hyperloglog :底层是String类型。用来统计网址的UV。bitmap :通过bit单位进行0或者1的设置,表示某个元素的状态,可以用来统计用户信息,如粉丝活跃数,登陆状态等。还可以用来做过滤器。
2.Redis为什么快
Redis是完全基于内存操作,使用单线程的操作效率是最高的,多线程会上下文切换消耗大量的时间。Redis操作数据库是基于内存操作,CPU并不是瓶颈,Redis的瓶颈是根据机器的内存和网络带宽。Redis6.0版本引入了多线程,多线程是在网络I/O处理方面使用的,如网络数据的读写和协议解析等,但是Redis执行命令的核心模块还是单线程的。Redis6.0中,多线程机制默认是关闭的,需要在redis.conf中完成两个设置启用多线程。
3.Redis的持久化(RDB和AOF)
RDB持久化
RDB(Redis DataBase)就是在指定的时间间隔内将内存中的数据集快照写入磁盘,数据恢复时将快照文件直接再读到内存。RDB 保存了在某个时间点的数据集(全部数据)。存储在一个二进制文件中,只有一个文件。默认是 dump.rdb。RDB 技术非常适合做备份,可以保存最近一个小时,一天,一个月的全部数据。保存数据是在单独的进程中写文件,不影响 Redis 的正常使用。RDB 恢复数据时比其他 AOF 速度快。redis通过一定的条件判断,是否需要将内存中数据写入到磁盘中,在服务器启动时会去读取磁盘中的dump.rdb问将数据写入到内存中去。指定时间间隔将数据持久化到硬盘。执行shutdown命令,flushdb会直接将数据写入到硬盘中。 优点 :数据恢复十分方便,比AOF要快。 缺点 :1.会丢失最后一次快照以后进来修改的数据。2.需要分配一个子进程来操作磁盘,占用一定的CPU。
AOF持久化
Append-only File(AOF),Redis 每次接收到一条改变数据的命令时,它将把该命令写到一个 AOF 文件中(只记录写操作,读操作不记录),当 Redis 重启时,它通过执行 AOF 文件中所有的命令来恢复数据。aop是文件追加,通过记录每次set key的记录,追加到一个文件中,在启动服务器时,将这些命令全部执行过去,大数据时效率较慢. aof文件被破坏时,可以通过redis-check-aof --fix appendonly.aof 文件名修复,这个过程会丢失部分数据。
appendfsync no
appendfsync always
appendfsync everysec
auto-aof-rewrite-min-size
优点 :数据完整性比RDB好。 缺点 :aof文件会在操作过程中越来越大,大数据启动比RDB慢。
4.Redis的过期键删除策略
定时删除 :通过设置key的过期时间来删除key,该策略会立即清除过期的数据,对内存不友好,会占用大量的CPU资源处理过期的数据,从而影响缓存的响应速度和吞吐量。惰性删除 :同访问一个key判断其是否已经过期,过期则清除key。节省了CPU的资源,会导致内存占用问题。可能出现大量过期的key没有被再次访问,导致不会被清除。定期删除 :通过定时扫描数据库中的key,并清除已经过期的key。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
5.Redis集群(主从复制)
通过持久化功能,Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,但是由于数据是存储在一台服务器上的,如果这台服务器出现故障,比如硬盘坏了,也会导致数据丢失。 为了避免单点故障,我们需要将数据复制多份部署在多台不同的服务器上,即使有一台服务器出现故障其他服务器依然可以继续提供服务。 我们可以通过部署多台 redis,并在配置文件中指定这几台Redis之间的主从关系,主负责写入数据,同时把写入的数据实时同步到从机器,这种模式叫做主从复制,即master/slave,并且Redis默认master用于写,slave用于读,向slave写数据会导致错误。 Redis默认每个服务端都是master,每个slave只能有一个master。
通过命令建立主从关系
slaveof master_host port
Ok
127.0.0.1:6379> slaveof 196.168.144.130 6379
OK Already connected to specified master
127.0.0.1:6379> set k1 v1
(error) READONLY You can't write against a read only replica.
slaveof no one
单机多端口搭建集群
include /usr/local/bin/config/redis.conf
port 6380
logfile "6380.log"
dbfilename dump6380.rdb
pidfile /var/run/redis_6380.pid
include /usr/local/bin/config/redis.conf
port 6381
logfile "6381.log"
dbfilename dump6381.rdb
pidfile /var/run/redis_6381.pid
port
logfile
dbfilename
pidfile
测试命令
redis-server config/redis.conf
redis-server config/redis6381.conf
redis-server redis6380.conf
slaveof 127.0.0.1 6379
slaveof 127.0.0.1 6379
注意点:
- 通过命令的方式配置的主从关系,重新启动后没有效果。
- 主节点宕机,slaveof no one,从节点变成主节点,主节点连接上也没有用,从节点还是主节点。
- 一个master可以有多个slave,一个slave只能有一个master。
复制原理
通过测试也能发现,设置server为slave就会在./目录下生成一个配置.rdb文件,就是slave启动之后就会连接到master发送一个同步sync命令,master接到命令,启动后台存盘进程,同时收集所有接收到的用户修改的的数据集的命令,在后台进程执行完毕之后,master将整个数据文件送到slave,并完成一次完全同步。
全量复制 :salve服务在启动后就会连接master发送一个请求,去获取mater当前最新的rdb快照,master不再将临时的写入rfb文件覆盖之前的rdb文件,而是将这个文件传输给slave服务器,而在某种情况下才会覆盖原有的rdb文件。
增量复制 :slave初始化后,开始正常工作,此时master服务器发生的写操作同步到从服务器的过程。
无磁盘复制 :子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储。
master服务器会开启一个后台进程用于将redis中的数据生成一个rdb文件,与此同时,服务器会缓存所有接收到的来自客户端的写命令(包含增、删、改),先将该rdb文件传递给slave服务器,而slave服务器会将rdb文件保存在磁盘并通过读取该文件将数据加载到内存,在此之后master服务器会将在此期间缓存的命令通过redis传输协议发送给slave服务器,然后slave服务器将这些命令依次作用于自己本地的数据集上最终达到数据的一致性。
情况模拟:使用java程序连接一个master服务器,通过循环写入100000条数据,启动java程序后,启动master的slave服务器,这个时候: 54秒,kill -9 9万条数据。 37秒 ,kill 带保存数据的命令12万的数据。 50秒左右 kill -9 11万条数据。 53秒 kill -9 master进程 18万数据在slave master只有10485条数据。 53秒 kill -9 salve 5816条数据。 53秒之后 1秒多 kill -9 master 581。 53秒 kill -9 salve 0条数据。 53秒之后 1秒多 kill -9 master 4200数据。
主从复制特点
- Redis使用异步复制。但从Redis 2.8开始,从服务器会周期性的应答从复制流中处理的数据量。
- 一个主服务器可以有多个从服务器。
- 从服务器也可以接受其他从服务器的连接。除了多个从服务器连接到一个主服务器之外,多个从服务器也可以连接到一个从服务器上,形成一个图状结构。
- Redis主从复制不阻塞主服务器端。也就是说当若干个从服务器在进行初始同步时,主服务器仍然可以处理请求。
- 主从复制也不阻塞从服务器端。当从服务器进行初始同步时,它使用旧版本的数据来应对查询请求,假设你在redis.conf配置文件是这么配置的。否则的话,你可以配置当复制流关闭时让从服务器给客户端返回一个错误。但是,当初始同步完成后,需要删除旧的数据集和加载新的数据集,在这个短暂的时间内,从服务器会阻塞连接进来的请求。
- 主从复制可以用来增强扩展性,使用多个从服务器来处理只读的请求(比如,繁重的排序操作可以放到从服务器去做),也可以简单的用来做数据冗余。
- 使用主从复制可以为主服务器免除把数据写入磁盘的消耗:在主服务器的redis.conf文件中配置“避免保存”(注释掉所有“保存“命令),然后连接一个配置为“进行保存”的从服务器即可。但是这个配置要确保主服务器不会关机。
高可用哨兵模式
Sentinel 哨兵是 redis 官方提供的高可用方案,可以用它来监控多个 Redis 服务实例的运行情况。Redis Sentinel 是一个运行在特殊模式下的 Redis 服务器。Redis Sentinel 是在多个Sentinel 进程环境下互相协作工作的。
Sentinel 系统有三个主要任务:
- 监控:Sentinel 不断的检查主服务和从服务器是否按照预期正常工作。
- 提醒:被监控的 Redis 出现问题时,Sentinel 会通知管理员或其他应用程序。
- 自动故障转移:监控的主 Redis 不能正常工作,Sentinel 会开始进行故障迁移操作。将一个从服务器升级新的主服务器。让其他从服务器挂到新的主服务器。同时向客户端提供新的主服务器地址。
port 26379
sentinel monitor mymaster 127.0.0.1 6380 2
redis-sentinel sentinel.conf配置文件地址
哨兵工作原理
- Sentinel 会不断检查 Master 和 Slave 是否正常。
- 如果 Sentinel进程挂了,就无法监控,所以需要多个哨兵,组成 Sentinel 网络,一个健康的Sentinel 至少有 3 个 Sentinel 应用。彼此在独立的物理机器或虚拟机。
- 监控同一个 Master 的 Sentinel 会自动连接,组成一个分布式的 Sentinel 网络,互相通信并交换彼此关于被监控服务器的信息。
- 当一个 Sentinel 认为被监控的服务器已经下线时,它会向网络中的其它 Sentinel 进行确认,判断该服务器是否真的已经下线。
- 如果下线的服务器为主服务器,那么 Sentinel 网络将对下线主服务器进行自动故障转移,通过将下线主服务器的某个从服务器提升为新的主服务器,并让其从服务器转移到新的主服务器下,以此来让系统重新回到正常状态。
- 下线的旧主服务器重新上线,Sentinel 会让它成为slave,挂到新的master下。
哨兵模式下会修改redis.conf配置文件。 当所有的服务都宕机时,sentinel会说明在一个指定时间之前不会执行故障转移。
6.Redis性能解决方案
主服务器免除把数据写入磁盘的消耗,不进行任何持久化工作。可以通过一个slave服务器开启AOF备份数据,策略设置每秒同步一次。为了主从复制的速度和连接的稳定性,master和slave最好在同一个局域网。
7.如何保证Redis与数据库的一致性问题
|