Redis

概念:key-value 存储系统,是跨平台的非关系型数据库。

特点

  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

  • Redis支持数据的备份,即master-slave模式的数据备份。

  • 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

  • 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

五大数据结构:

String(字符串)

key--valuestring 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。

Hash(哈希)

key对应(key-value)集合 key---filed---value
Redis hash 是一个键值(key=>value)对集合。
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
每个 hash 可以存储 232 -1 键值对(40多亿)。

List(有序列表) 例如:rpush list 1 2 3 4

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

Set(无序唯一集合)例如: sadd set1 a b c d

Redis 的 Set 是 string 类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
集合中最大的成员数为 232 - 1(4294967295, 每个集合可存储40多亿个成员)。

zset(sorted set:有序唯一集合) 例如: zadd zset1 9 a 8 c 10 d 1 e

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。

事务

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做,所有指令要不全部执行要不全部不执行,失败也不会回滚

事务相关的几个命令:

1

DISCARD

取消事务,放弃执行事务块内的所有命令。

2

EXEC

执行所有事务块内的命令。

3

MULTI

标记一个事务块的开始。

4

UNWATCH

取消 WATCH 命令对所有 key 的监视。

5

WATCH key [key ...](实现乐观锁 )

监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。

Redis GEO

Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。

Redis GEO 操作方法有:

    • geoadd:添加地理位置的坐标。

    • geopos:获取地理位置的坐标。

    • geodist:计算两个位置之间的距离。

    • georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。

    • georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。

    • geohash:返回一个或多个位置对象的 geohash 值。

Redis 管道技术

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

    • 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。

    • 服务端处理命令,并将结果返回给客户端。

Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

例:   $(echo -en "PING\r\n SET runoobkey redis\r\nGET runoobkey\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379

Redis持久化

AOF(append only file)

fork子进程,以日志形式记录每次写操作,将redis执行的所有指令记录下来,只许追加文件但不可以改写文件,redis启动时会读取该文件重新构建数据,即重启时候会执行日志中记录的所有写命令,效率低

RDB

  生成.rdb结尾文件。redis单独fork一个子进程来持久化---将内存内容写入临时rdb文件----快照完成后替换原来快照文件,子进程退出----生成正式rdb文件。此方式效率高,适合大规模数据恢复。因为需要一定时间间隔操作,所以redis挂掉后最后一次操作数据不会被持久化

fork进程的时候会占用一定内存空间

Redis过期策略  

定时过期:每秒10次一直扫描key,查看是否过期,消耗CPU,对内存友好

惰性策略:只有访问时候才会检查是否过期,容易造成大量冗余过期数据,对内存不友好

定期过期:定时去检查

Redis内存淘汰策略(缓存回收策略)

内存不足时候,释放空间:设置最大内存,四种淘汰机制:

1、淘汰最少访问的一些key(推荐  allkeys-lru)

2、随机淘汰一些

3、移除快过期的key

4、报错

Redis集群

        常见集群分类:主从复制和分片集群

        redis集群:主从复制,主从哨兵模式,客户端实现路由索引分片集群,中间件代理层分片集群,redis本身实现的cluster分片集群

主从配置:

配置conf文件

role:

master_host:

master_port:

...

哨兵模式:

原理机制:

三个定时任务

sentinel在内部有3个定时任务

1.每10秒每个sentinel会对master和slave执行info命令

这个任务达到两个目的:发现slave节点--------确认主从关系

2.每2秒每个sentinel通过master节点的channel交换信息(pub/sub)

master节点上有一个发布订阅的频道(__sentinel__:hello)。

sentinel节点通过__sentinel__:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

3.每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控)

这个其实是一个心跳检测,是失败判定的依据。

主观下线和客观下线

在redis-sentinel的conf文件里有这么两个配置:

1.sentinel monitor <masterName> <ip> <port> <quorum>

四个参数含义:

masterName这个是对某个master+slave组合的一个区分标识(一套sentinel是可以监听多套master+slave这样的组合的)。

ip 和 port 就是master节点的 ip 和 端口号。

quorum这个参数是进行客观下线的一个依据,意思是至少有 quorum 个sentinel主观的认为这个master有故障,才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

2.sentinel down-after-milliseconds <masterName> <timeout>

这个配置其实就是进行主观下线的一个依据,masterName这个参数不用说了,timeout是一个毫秒值,表示:如果这台sentinel超过timeout这个时间都无法连通master包括slave(slave不需要客观下线,因为不需要故障转移)的话,就会主观认为该master已经下线(实际下线需要客观下线的判断通过才会下线)

那么,多个sentinel之间是如何达到共识的呢?

这就是依赖于前面说的第二个定时任务,某个sentinel先将master节点进行一个主观下线,然后会将这个判定通过sentinel is-master-down-by-addr这个命令问对应的节点是否也同样认为该addr的master节点要做客观下线。最后当达成这一共识的sentinel个数达到前面说的quorum设置的这个值时,就会对该master节点下线进行故障转移。quorum的值一般设置为sentinel个数的二分之一加1,例如3个sentinel就设置2

领导者选举

为什么要选领导者?因为只能有一个sentinel节点去完成故障转移

sentinel is-master-down-by-addr这个命令有两个作用,一是确认下线判定,二是进行领导者选举。

选举过程:

1.每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。

2.收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。

3.如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者

4.如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。

故障转移

所谓故障转移就是当master宕机,选一个合适的slave来晋升为master的操作,redis-sentinel会自动完成这个,不需要我们手动来实现。

那么,如何选择一个合适的slave呢?顺序如下:

1.选择slave-priority(slave节点优先级配置)最高的slave节点,(默认都是一样的)例如:如果我们有两台slave在两台机器上,一台配置较高,我们希望当master挂掉优先选配置高的,就可以配置该值为slave中最高的。如果存在最高则返回,不存在继续

2.选择复制偏移量最大的节点(复制得最完整,与master节点的数据一致性更高),如果存在则返回,不存在继续

3.如果以上两个条件都不满足,选runId最小的(启动最早的)。

补充一点:还可以向任意sentinel发生sentinel failover <masterName> 进行手动故障转移,这样就不需要经过上述主客观和选举的过程。

 

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值