前言
本博客为个人复习时总结用,无商业目的,其大多数内容皆为博主整理所得,并非原创。侵删。
nosql
为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。(非关系型数据库)
redis
Redis是使用c语言开发的一个高性能键值数据库。Redis可以通过一些键值类型来存储数据。
键值类型:
- String字符类型
- map散列类型
- list列表类型
- set集合类型
- sortedset有序集合类型
应用场景:
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
分布式集群架构中的session分离。
- 聊天室的在线好友列表。
任务队列。(秒杀、抢购、12306等等)
- 应用排行榜。
- 网站访问统计。
- 数据过期处理(可以精确到毫秒)
Redis数据类型
https://www.cnblogs.com/sdgf/p/6244937.html
redis 数据结构:
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- String——字符串
- Hash——字典
- List——列表
- Set——集合
- Sorted Set——有序集合Zset
下面我们就来简单说明一下它们各自的使用场景:
Redis持久化方案
-
Rdb方式
Redis默认的方式,redis通过快照来将数据持久化到磁盘中。 -
设置持久化快照的条件
在redis.conf中修改持久化快照的条件,如下:
save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。
Rdb问题
一旦redis非法关闭,那么会丢失最后一次持久化之后的数据。
如果数据不重要,则不必要关心。
如果数据不能允许丢失,那么要使用aof方式。
Aof方式
Redis默认是不使用该方式持久化的。Aof方式的持久化,是操作一次redis数据库,则将操作的记录存储到aof持久化文件中。
结论
在使用aof和rdb方式时,如果redis重启,则数据从aof文件加载。
Redis的主从复制
什么是主从复制
持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:
说明:
主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。
- 主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。`
只有一个主redis,可以有多个从redis。
- 主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求
- 一个redis可以即是主又是从,如下图:
注意:
-
主机一旦发生增删改操作,那么从机会将数据同步到从机中
-
从机不能执行写操作
127.0.0.1:6380> set s2 222 (error) READONLY You can't write against a read only slave.
Redis集群
redis-cluster架构图
架构细节:
- 所有的redis节点彼此互联
(PING-PONG机制),
内部使用二进制协议优化传输速度和带宽. - 节点的fail是通过集群中
超过半数的节点检测
失效时才生效. - 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
- redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
示例如下:
redis-cluster投票:容错
-
集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉.
-
什么时候整个集群不可用(cluster_state:fail)?
- 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
- 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。
驱逐策略:
- noeviction:
不删除策略,
达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。 大多数写命令都会导致占用更多的内存(有极少数会例外, 如 DEL )。 - allkeys-lru: 所有key通用;
优先删除最近最少使用(less recently used ,LRU) 的 key。
- volatile-lru: 只限于设置了 expire 的部分;
优先删除最近最少使用(less recently used ,LRU) 的 过期key。
- allkeys-random: 所有key通用;
随机删除一部分 key。
- volatile-random: 只限于设置了 expire 的部分;
随机删除一部分过期 key。
- volatile-ttl: 只限于设置了 expire 的部分;
优先删除剩余时间(time to live,TTL) 短的key。
如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。
Redis Expire 命令用于设置 key 的过期时间,key 过期后将不再可用。单位以秒计。
驱逐过程可以这样理解:
客户端执行一个命令, 导致 Redis 中的数据增加,占用更多内存。
Redis 检查内存使用量, 如果超出 maxmemory 限制, 根据策略清除部分 key。
继续执行下一条命令, 以此类推。
在这个过程中, 内存使用量会不断地达到 limit 值, 然后超过, 然后删除部分 key, 使用量又下降到 limit 值之下。
如果某个命令导致大量内存占用(比如通过新key保存一个很大的set), 在一段时间内, 可能内存的使用量会明显超过 maxmemory 限制。