Redis本质上是一个Key-Value类型的内存数据库,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作,是已知性能最快的Key-Value DB。
Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB。另外Redis也可以对存入的Key-Value设置expire时间。 Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
1. Redis数据结构及命令操作
1.1 基本概念及操作
- 默认16个数据库,类似数组下表从零开始,初始默认使用零号库;
- 统一密码管理,16个库都是同样密码,要么都OK要么一个也连接不上,redis默认端口是6379;
- select命令切换数据库:select 0-15;
- dbsize:查看当前数据库的key的数量;
- flushdb:清空当前库;
- flushall;通杀全部库;
1.2 Redis数据结构
redis存储的是:key-value格式的数据,其中key都是字符串,value有5种不同的数据结构:String、Hash、List、Set、Zset(Sorted Set)
- String:set, get, del, append, strlen
- Hash:hset, hget, hdel, hmset(批量设值), hmget, hgetall
- List:lpush, rpush, lrange, lpop(删除), rpop, lindex
- Set:sadd, smembers, srem(根据可以移除member), sismember(判断是否为key的成员)
- ZSet:zadd, zrange, zrem
1.3 Redis键(key)–常用命令介绍
- keys *:查看所有 key ;
- exists key的名字:判断某个 key 是否存在;
- move key dbID(0-15): 当前库就没有了,被移除了;
- expire key 秒钟: 为给定的 key 设置过期时间;
- ttl key: 查看还有多少秒过期,-1表示永不过期,-2表示已过期;
- type key: 查看你的 key 是什么类型;
2. Redis持久化
Redis作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客户端请求时,所有操作都在内存当中进行,为了避免内存中数据丢失,Redis提供了RDB和AOF两种不同的数据持久化方式。
2.1 RDB(Redis DataBase)
RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。
- 开启RDB持久化方式一:save命令,或bgsave(异步)
- 开启方式二:在Redis配置文件redis.conf配置,配置完后启动时加载:
redis-server redis.conf
1 | save 900 1 # 900s内至少达到一条写命令 |
RDB的几个优点
- 与AOF方式相比,通过rdb文件恢复数据比较快。
- rdb文件非常紧凑,适合于数据备份。
- 通过RDB进行数据备,由于使用子进程生成,所以对Redis服务器性能影响较小。
RDB的几个缺点
- 如果服务器宕机的话,采用RDB的方式会造成某个时段内数据的丢失,比如我们设置10分钟同步一次或5分钟达到1000次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这个时间段的数据会丢失。
- 使用save命令会造成服务器阻塞,直接数据同步完成才能接收后续请求。
- 使用bgsave命令在forks子进程时,如果数据量太大,forks的过程也会发生阻塞,另外,forks子进程会耗费内存。
2.2 AOF(Append-only file)
与RDB存储某个时刻的快照不同,AOF持久化方式会记录客户端对服务器的每一次写操作命令(以日志的形式),并将这些写操作以Redis协议追加保存到以后缀为aof文件末尾,在Redis服务器重启时,会加载并运行aof文件的命令,以达到恢复数据的目的。
- 开启方式:在Redis配置文件redis.conf配置
1 | appendonly yes # 开启aof机制 |
- aof文件太大,加载aof文件恢复数据时,就会非常慢,为了解决,Redis通过重写aof,可以生成一个恢复当前数据的最少命令集,两种方式:配置no-appendfsync-on-rewrite(默认no),或者客户端向服务器发送bgrewriteaof命令
- AOF的优点:AOF只是追加日志文件,因此对服务器性能影响较小,速度比RDB要快,消耗的内存较少。
- AOF的缺点:AOF方式生成的日志文件太大,即使通过AFO重写,文件体积仍然很大。恢复数据的速度比RDB慢。
- 当RDB与AOF两种方式都开启时,Redis会优先使用AOF日志来恢复数据,因为AOF保存的文件比RDB文件更完整。
2.2.1 AOF文件修复
- 备份被写坏的AOF文件
- 运行redis-check-aof –fix进行修复
- 用diff -u来看下两个文件的差异,确认问题点
- 重启redis,加载修复后的AOF文件
3. Redis的高并发和快速原因
- redis是基于内存的,内存的读写速度非常快;
- redis是单线程的,省去了很多上下文切换线程的时间;
- redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间。
- 另外,数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
- 还有一点,Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。
4. Redis利用哨兵(Sentinel),复制(Replication)这两个功能来保证高可用
- 哨兵(Sentinel):可以管理多个Redis服务器,它提供了监控,提醒以及自动的故障转移的功能。
- 集群监控:负责监控Redis master和slave进程是否正常工作
- 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
- 故障转移:如果master node挂掉了,会自动转移到slave node上
- 配置中心:如果故障转移发生了,通知client客户端新的master地址
- 复制(Replication):则是负责让一个Redis服务器可以配备多个备份的服务器。
- 从数据库向主数据库发送sync(数据同步)命令。
- 主数据库接收同步命令后,会保存快照,创建一个RDB文件。
- 当主数据库执行完保持快照后,会向从数据库发送RDB文件,而从数据库会接收并载入该文件。
- 主数据库将缓冲区的所有写命令发给从服务器执行。
- 以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。
5. Redis 主从复制、哨兵和集群这三个有什么区别
主从复制是为了数据备份,哨兵是为了高可用,Redis主服务器挂了哨兵可以切换,集群则是因为单实例能力有限,搞多个分散压力。
- 主从模式:读写分离,备份,一个Master可以有多个Slaves。
- 哨兵entinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器。
- 集群Cluster:为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性。
6. Redis Cluster集群
Redis Cluster,是Redis 3.0开始引入的分布式存储方案。
集群由多个节点(Node)组成,Redis的数据分布在这些节点中。集群中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。
- 集群的作用:
- 数据分区:数据分区(或称数据分片)是集群最核心的功能。
- 高可用:集群支持主从复制和主节点的自动故障转移(与哨兵类似);当任一节点发生故障时,集群仍然可以对外提供服务。
6.1 Redis Cluster集群的搭建可以分为四步:
- 启动节点:将节点以集群模式启动,此时节点是独立的,并没有建立联系;
- 节点握手:让独立的节点连成一个网络;
- 分配槽:将16384个槽分配给主节点;
- 指定主从关系:为从节点指定主节点。
6.2 Redis Cluster工作原理
- 客户端与Redis节点直连,不需要中间Proxy层,直接连接任意一个Master节点
- 根据公式
HASH_SLOT=CRC16(key) mod 16384
,计算出映射到哪个分片上,然后Redis会去相应的节点进行操作
1 | CRC16(key) | 0~5460 | <--Slot--|Redis(M)|<---|Redis(S可多个从) |
6.3 Redis Cluster优点:
- 无需Sentinel哨兵监控,如果Master挂了,Redis Cluster内部自动将Slave切换Master
- 可以进行水平扩容
- 支持自动化迁移,当出现某个Slave宕机了,那么就只有Master了,这时候的高可用性就无法很好的保证了,万一master也宕机了,咋办呢? 针对这种情况,如果说其他Master有多余的Slave ,集群自动把多余的Slave迁移到没有Slave的Master 中。
6.4 Redis Cluster缺点:
- 批量操作是个坑(不同的key会划分到不同的slot中,因此直接使用mset或者mget等操作是行不通)
- 资源隔离性较差,容易出现相互影响的情况。
6.5 Redis Cluster总结:
- Redis Cluster集群架构,不同的key是有可能分配在不同的Redis节点上的,在这种情况下Redis的事务机制是不生效。
- 单机下的redis可以支持16个数据库(db0 ~ db15),在Redis Cluster集群架构下只有一个数据库空间,即db0。
- 不同的key会划分到不同的slot中,因此直接使用mset或者mget等操作是行不通。
- 如果Hash对象非常大,是不支持映射到不同节点的!只能映射到集群中的一个节点上。
- Redis集群模式下进行批量操作:如果执行的key数量比较少,就用串行get操作; 如果需要执行的key很多,就使用Hashtag保证这些key映射到同一台redis节点上。
- Redis Cluster的架构,是属于分片集群的架构,不做读写分离,因为redis本身在内存上操作,不会涉及IO吞吐,即使读写分离也不会提升太多性能,Redis在生产上的主要问题是考虑容量,单机最多10-20G,key太多降低redis性能.因此采用分片集群结构,已经能保证了我们的性能。其次,用上了读写分离后,还要考虑主从一致性,主从延迟等问题,徒增业务复杂度。