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通知状态

  1. +reset-master <instance details> :主服务器已被重置。

  2. +slave <instance details> :一个新的从服务器已经被 Sentinel 识别并关联。

  3. +failover-state-reconf-slaves <instance details> :故障转移状态切换到了 reconf-slaves 状态。

  4. +failover-detected <instance details> :另一个 Sentinel 开始了一次故障转移操作,或者一个从服务器转换成了主服务器。

  5. +slave-reconf-sent <instance details> :领头(leader)的 Sentinel 向实例发送了SLAVEOF命令,为实例设置新的主服务器。

  6. +slave-reconf-inprog <instance details> :实例正在将自己设置为指定主服务器的从服务器,但相应的同步过程仍未完成。

  7. +slave-reconf-done <instance details> :从服务器已经成功完成对新主服务器的同步。

  8. -dup-sentinel <instance details> :对给定主服务器进行监视的一个或多个 Sentinel 已经因为重复出现而被移除 —— 当 Sentinel 实例重启的时候,就会出现这种情况。

  9. +sentinel <instance details> :一个监视给定主服务器的新 Sentinel 已经被识别并添加。

  10. +sdown <instance details> :给定的实例现在处于主观下线状态。

  11. -sdown <instance details> :给定的实例已经不再处于主观下线状态。

  12. +odown <instance details> :给定的实例现在处于客观下线状态。

  13. -odown <instance details> :给定的实例已经不再处于客观下线状态。

  14. +new-epoch <instance details> :当前的纪元(epoch)已经被更新。

  15. +try-failover <instance details> :一个新的故障迁移操作正在执行中,等待被大多数 Sentinel 选中(waiting to be elected by the majority)。

  16. +elected-leader <instance details> :赢得指定纪元的选举,可以进行故障迁移操作了。

  17. +failover-state-select-slave <instance details> :故障转移操作现在处于 select-slave 状态 —— Sentinel 正在寻找可以升级为主服务器的从服务器。

  18. no-good-slave <instance details> :Sentinel 操作未能找到适合进行升级的从服务器。Sentinel 会在一段时间之后再次尝试寻找合适的从服务器来进行升级,又或者直接放弃执行故障转移操作。

  19. selected-slave <instance details> :Sentinel 顺利找到适合进行升级的从服务器。

  20. failover-state-send-slaveof-noone <instance details> :Sentinel 正在将指定的从服务器升级为主服务器,等待升级功能完成。

  21. failover-end-for-timeout <instance details> :故障转移因为超时而中止,不过最终所有从服务器都会开始复制新的主服务器(slaves will eventually be configured to replicate with the new master anyway)。

  22. failover-end <instance details> :故障转移操作顺利完成。所有从服务器都开始复制新的主服务器了。

  23. +switch-master <master name> <oldip> <oldport> <newip> <newport> :配置变更,主服务器的 IP 和地址已经改变。 这是绝大多数外部用户都关心的信息。

  24. +tilt :进入 tilt 模式。

  25. -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)    收藏  举报

导航