Redis
redis文档:http://redisdoc.com/string/set.html
redis实现分布式锁两种方式:https://www.cnblogs.com/chenjianxiang/p/8981134.html
redisson实现分布式锁:https://www.cnblogs.com/zhongkaiuu/p/redisson.html
五种数据类型使用场景:https://blog.csdn.net/wender/article/details/78531192
redis编译:yum install gcc tcl -y
[root@node01 redis-2.8.18]# make && make PREFIX=/opt/lzx/redis install //2.8单机版,3.x之后才有集群
注册服务:[root@node01 utils]# vim /etc/profile //配置redis环境变量
export REDIS_HOMW=/opt/lzx/redis
[root@node01 utils]# ./install_server.sh
[root@node01 utils]# service redis_6379 status 查看redis服务是否启动
[root@node01 utils]# redis-cli -p 6380 指定端口
127.0.0.1:6379> help @string 查看api
redis key是二进制安全的,意味着redis字符串能包含任意类型的数据,不会影响数据展示,客户端会影响展示(编码),最多512M
登录不同的库:redis-cli -n 2
清除当前库数据:flushdb
清除所有库中的数据:flushall
key pattern=>pattern取值:*任意长度字符
?任意一个字符
[]字符集合,表示可以是集合中的任意一个
set k1 中a---->utf-8 长度4 中文看不了
redis-cli --raw就可以看到中文
GETRANGE正向从0开始,负向索引从-1开始,按字节取
incr key 增加1 针对value是否为int类型,OBJECT encoding key
decr key 减1
发生在redis中,但是memcache是要取回值后计算,再存回去
bit操作:
1.设置某一位上的值:SETBIT key offset value (0/1) 从0位开始
结果:0100 0000 不超过一个字节
结果:0100 0000 1000 0000
2.返回指定值0或者1在指定区间上第一次出现的位置偏移量
BITPOS key bit start end
3.统计指定为区间上值位1的数量
BITCOUNT key start end
bitmap:用户的上线次数统计(活跃用户)
用户id为key,天作为offset,上线置为1 假设一年366天
最后bitcount key 0 -1 //统计所有天数
列表:基于LinkedList实现,最多包含2^32 -1元素
1.![]()
2.![]()
同向操作为栈,异向操作位队列
3.![]()
4.![]()
5.![]()
6.消息队列
7.Hash:一个hash最多包含2^32-1键值对 结构形式:key->map
使用:微博的好友关注,关注数、粉丝数、喜欢的商品数、发帖数等
HSET user:1111 follow 5
HINCRIBY user:1111 follow 1
优点:1.节约内存空间
2.redis每创建一个键,都会为该键存储一些附加管理信息(比如键的类型,最后一次被访问的时间)
3.key越多,redis服务器在存储管理信息方面耗费的内存会越多,浪费内存和cpu
a.设置单个字段:
1.HSET key field value
2.HSETNX key field value 注:key的fied不存在的情况下执行,key不存在直接创建
b.设置多个字段
1.HMSET key field value [field value ...]
c.返回字段个数
1.HLEN key
d.判断字段是否存在
1.HEXISTS key field key或field不存在,返回0
e.返回字段值
1.HGET key field
f.返回多个字段值
1.HMGET key field[filed...]
g.返回所有的键值对
HGETALL key
h.返回所有字段名
HKEYS key
i.返回所有值
HVALS key
j.在字段对应的值上进行整数的增量计算
HINCRBY key field increment
k.在字段对应的值上进行浮点数增量计算
HINCRBYFLOAT key field increment
l.删除指定的字段
HDEL key field[filed ...]
8.SET集合:
1.无需去重、元素为字符串类型、最多包含2^32-1个元素
2.增加一个或多个元素(如果元素已经存在,则忽略)
SADD kkk a b c
SREM kkk a b 移除
3.返回集合包含的所有元素
SMEMBERS key (如果集合元素过多,可能会造成服务器阻塞,生产环境慎重使用)
4.检查指定元素是否在集合中
SISMENMBER key member
5.随机返回集合中指定个数的集合(例子:抽奖)
SRANDMEMBER key count (count为正数,则取集合count个元素;为负数,返回非去重集合,数量为count绝对值;
不指定count,随机返回一个元素;如果count为0,返回空)
6.返回集合中元素的个数
SCARD key 键的结果会保存信息,集合长度就记录在里面,无需再遍历
SPOP key 随机从集合中移除并返回该元素
SMOVE source destination member 将元素从源集合移动到目标集合
7.取差集:
SDIFF key [key...] 从第一个key的集合中去除其他集合和自己的交集部分(具有方向性)
SDIFFSTORE destination key[key...] 将差集结果存储在目标key中
8.取交集
SINTER key [key...] 取所有集合的交集部分
SINTERSTORE destination key[key...] 将交集结果存储在目标key中
9.取并集,并去重
SUNION key[key...] 取所有集合的并集,并去重SUNIONSTORE destination key[key...] 将并集集结果存储在目标key中
10.实际使用场景:
9.SortedSET:有序集合
1.类似Set集合、有序且去重、元素是字符串类型、每个元素都关联着一个浮点数分支(Score),并按分值从小到大、最多包含2^32-1
2.ZADD key score member //如果元素已存在,则使用新的score
例如:ZADD kkk 1.0 k1 2.0 k2
3.ZREM key member member //元素不存在时,自动忽略
ZREM kkk k1 k2
4.ZSCORE kkk k1 //显示k1的分数
5.ZINCRBY key increment number //increment为负数就是减少
6.ZRANK key member //返回从小到大元素的排名(索引:分为正负,)
ZREVRANK key member //返回从大到小元素的排名 //应用场景:取听歌曲、排名前几
逆序同理:
集合(尤其是并集)运算,容易会造成redis服务器阻塞,最好放在空闲时间或备用服务器上使用
ZREMRANGEBYSCORE命令删除的有序集合保存在key的最小值和最大值(含)之间的分数的所有元素
ZREMRANGEBYRANK key start stop //移除指定排名范围的元素
9.redis持久化:将数据从掉电易失的内存中存放到永久存储的设备上
a.redis为什么持久化?
基于内存的,掉电易失数据
作为缓存服务器,看实际情况(数据重要性)再判断需要持久化
作为内存数据库,建议需要持久化
作为消息队列,根据前端消息能否再产生数据、数据重要性来判断是否需要持久化
b.RDB(Redis DB) 类比 hdfs:fsimage
默认情况下,Redis将数据库快照保存在名字为dump.rdb文件中
产生RDB方式:非实时
a.阻塞方式:客户端执行save命令;上线或运维停服维护,一般执行次数少
手动:客户端发起SAVE、BGSAVE命令
b.非阻塞方式(复杂度相对高,多数情况下选择此方式):bgsave
自动:按配置文件中的条件满足就执行BGSAVE,save 60 1000,Redis满足60秒内至少有1000个键被改动,会自动保存一次
由内核去完成父子进程备份操作
c.数据落rdb策略:主要是为了确保主进程正常运行,不影响机器运行
默认配置:只要满足以下其中一个条件,就自动进行备份,创建RDB文件后,时间计数器和计数器会清零
save 900 1 //900
save 300 10 //300秒内达到10次操作,写rdb
save 60 10000 //60秒内达到1W次操作,存储
dbfilename dump.rdb
dir /var/lib/redis/6379
AOF(AppendOnlyFile 实时操作) 类比 hdfs:edit logs //默认关闭的 系统->调用内核write->完成写操作
会占用内存性能,速度相对慢,一般只在数据重要性很高才用
AOF重写机制:
1.AOF文件过大
2.合并重复的操作,AOF会使用尽可能少的命令来记录
重写过程:会把重复冗余的操作精简合并成一次,最终命令精简
eg:重写前:SADD kkk "aa" SADD kkk "bb"
重写后:SADD kkk "aa" "bb"
1.fork一个子进程负责重写AOF文件
2.子进程会创建一个临时文件写入AOF信息
3.父进程会开辟一个内存缓冲区接收新的写命令
4.子进程重写完成后,父进程会获得一个信号,将父进程接收到的新的写操作由子进程写入到临时文件中
5.新文件替代旧文件
注:如果写入操作的时候出现故障导致命令写半截,可使用redis-check-aof工具修复
10.redis集群:
a.单机/单点:
1.都有性能瓶颈 2.都会遇到单点故障问题
b. 集群分类:
1.主从复制Replication:镜像:增删改(主<退化到单节点>)查询负载到从节点,比较脆弱
高可用Sentinel(多)
手动创建主从复制节点:先启动redis-server --port 6380,用于主节点
![]()
此时6380会触发BGSAVE,执行RDB策略(主从目录下都会生成dump.rdb文件);数据库同步时主从会有版本信息保持数据最终一致;
从节点只能读,不能写;主节点可读写
当主节点挂了,在从节点执行SLAVEOF no one,可以将从变为主,同时SLAVEOF 127.0.0.1 6381 拷贝哨兵(无主模型)到redis目录下:投票数为2
启动第三个哨兵,能监听到其他两个哨兵,主redis服务器和从服务器,当主挂了,重新选取一个从作为主(投票),但是时间要相对久一些(1分钟)
2.分布式 twemproxy:切片
问题:主从对写压力没有分担
解决思路:使用多个节点分担,将写请求分散到不同节点处理
分片Sharding:参考关系型数据库处理大表的水平切分思路
集群Cluster(twitter无主模型):
redis 3.0才开始有集群
从节点找不到数据时处理:
Redis Sentinel
Sentinel(哨兵)是用于监控redis集群中Master状态的工具,并在服务器发生故障时,进行自动故障转移,其已经被集成在redis2.4+的版本中
一、Sentinel作用:
1):Master状态检测
2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
3):Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
二、Sentinel工作方式:
1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。二、注意点: 1):首次启动时,必须先启动Master 2):Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态) 3):若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群。三、sentinel通知状态
+reset-master <instance details> :主服务器已被重置。
+slave <instance details> :一个新的从服务器已经被 Sentinel 识别并关联。
+failover-state-reconf-slaves <instance details> :故障转移状态切换到了 reconf-slaves 状态。
+failover-detected <instance details> :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。
+slave-reconf-sent <instance details> :领头(leader)的 Sentinel 向实例发送了SLAVEOF命令,为实例设置新的主服务器。
+slave-reconf-inprog <instance details> :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。
+slave-reconf-done <instance details> :从服务器已经成功完成对新主服务器的同步。
-dup-sentinel <instance details> :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。
+sentinel <instance details> :一个监视给定主服务器的新 Sentinel 已经被识别并添加。
+sdown <instance details> :给定的实例现在处于主观下线状态。
-sdown <instance details> :给定的实例已经不再处于主观下线状态。
+odown <instance details> :给定的实例现在处于客观下线状态。
-odown <instance details> :给定的实例已经不再处于客观下线状态。
+new-epoch <instance details> :当前的纪元(epoch)已经被更新。
+try-failover <instance details> :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by the majority)。
+elected-leader <instance details> :赢得指定纪元的选举,可以进行故障迁移操作了。
+failover-state-select-slave <instance details> :故障转移操作现在处于 select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。
no-good-slave <instance details> :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。
selected-slave <instance details> :Sentinel 顺利找到适合进行升级的从服务器。
failover-state-send-slaveof-noone <instance details> :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。
failover-end-for-timeout <instance details> :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。
failover-end <instance details> :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。
+switch-master <master name> <oldip> <oldport> <newip> <newport> :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。
+tilt :进入 tilt 模式。
-tilt :退出 tilt 模式。
四、故障转移
一次故障转移操作由以下步骤组成:
- 发现主服务器已经进入客观下线状态。
- 对我们的当前纪元进行自增(详情请参考 Raft leader election ), 并尝试在这个纪元中当选。
- 如果当选失败, 那么在设定的故障迁移超时时间的两倍之后, 重新尝试当选。 如果当选成功, 那么执行以下步骤。
- 选出一个从服务器,并将它升级为主服务器。
- 向被选中的从服务器发送
SLAVEOF NO ONE命令,让它转变为主服务器。 - 通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。
- 向已下线主服务器的从服务器发送 SLAVEOF 命令, 让它们去复制新的主服务器。
- 当所有从服务器都已经开始复制新的主服务器时, 领头 Sentinel 终止这次故障迁移操作。
每当一个 Redis 实例被重新配置(reconfigured) —— 无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器 —— Sentinel 都会向被重新配置的实例发送一个 CONFIG REWRITE 命令, 从而确保这些配置会持久化在硬盘里。
Sentinel 使用以下规则来选择新的主服务器:
- 在失效主服务器属下的从服务器当中, 那些被标记为主观下线、已断线、或者最后一次回复 PING 命令的时间大于五秒钟的从服务器都会被淘汰。
- 在失效主服务器属下的从服务器当中, 那些与失效主服务器连接断开的时长超过 down-after 选项指定的时长十倍的从服务器都会被淘汰。
- 在经历了以上两轮淘汰之后剩下来的从服务器中, 我们选出复制偏移量(replication offset)最大的那个从服务器作为新的主服务器; 如果复制偏移量不可用, 或者从服务器的复制偏移量相同, 那么带有最小运行 ID 的那个从服务器成为新的主服务器。
- 来源: https://wiki.lagou.com/pages/viewpage.action?pageId=12027058
posted on 2019-05-19 01:16 xiaojiayu0011 阅读(303) 评论(0) 收藏 举报
浙公网安备 33010602011771号