系统性能优化

redis常用命令备忘录

2021-02-16  本文已影响0人  渡边Hok

1.启动

1.1windows版本启动命令

    redis-server.exe ./redis.windows.conf

    redis-cli  

2.数据类型

 2.1.string    

        格式  set key value [EX seconds][PX milliseconds] [NX|XX]

        EX seconds : 将键的过期时间设置为 seconds 秒。

        PX milliseconds : 将键的过期时间设置为 milliseconds 毫秒。

        NX : 只在键不存在时, 才对键进行设置操作。 执行 SET key value NX 的效果等同于执行 SETNX key value

        XX : 只在键已经存在时, 才对键进行设置操作。 

在 Redis 2.6.12 版本以前, SET 命令总是返回 OK 。 

        set name dubian    //添加

        get name    //获取

        exists name    //判断key是否存在 0 存在 1 不存在

        del name //删除数据结构,所有数据结构都用该命令删除

        mset k1 v1 k2 v2 k3 v3 //批量读写可节省网络消耗开销

        mget k1 k2 k3

       过期策略

        expire name 5 //5s后过期

        setex name 5 dubian //等价于set+expire

    计数

        如果value是整数,可对value进行自增操作,范围是singed long最大最小值,超过报错

        set age 30  //OK

        incr age //31

        incrby age 4 //35

        incrby age -5 //30

2.2.list(列表)

    特点:相当于java的LinkedList,增删快定位慢。列表元素为空数据结构自动删除,内存回收(redis所有数据结构都有此特性)。list底层是一个快速链表quicklist,在元素较少时会使用一块连续的内存存储,称为压缩列表ziplist,当数据较多才会变为quicklist。

    队列FIFO:右边进左边出 

    栈:右边进右边出

    rpush key1 v1 v2 v3 //添加元素

    llen key1   //获取长度

    rpop key1       lpop key1 //弹出元素

    rpush key1 v1        rpush key1 v1  //添加元素

    lindex key1 1    //返回v2,相当于java链表的get(index)

    ltrim key1 1 2  //对列表进行截断操作,返回OK 。 Index可为负数,-1表示倒数第一个元素,可用于实现一个定长列表

    lrang key1 0 -1 //获取所有元素,O(n)谨慎使用

2.3.hash(字典)

    特点:相当于java的HashMap,同样是数组+链表的二维结构,不同的是,redis的字典采用的是渐进式rehash。渐进式rehash查询时会同时查询两个hash结构,然后在后续的定时任务和hash子指令中,循序渐进的将旧hash内容迁移到新hash中。

    hset key1 field1 v1  //如果字符串包含空格需要药引号括起来

    hgetall key1 //获取entry field与value间隔出现

    hget key1 field1 //获取指定field值

    hmset key1 field1 v1 field2 v2 field3 v3 //批量set

    hincrby dubian age 1 //单个field可进行计数

2.4.set(集合)

        特点:相当于java里的HashSet,其内部的键值是唯一无序的,内部实现相当于一个特殊字典,字典中所有的value都是NULL。set结构可以用来存储中奖用户id,因为有去重功能,保证同一个用户不会中奖两次。

    sadd key1 m1 m2 m3 //key1中若存在该member则返回0,否则返回1成功

    smembers key1 //获取所有member

    sismember key1 m1 //查询某个member是否存在,存在返回1,不存在返回0

    scard key1 //计数

2.5.zset有序列表

    特点:类似于SortSet和HashMap的结合体,一方面它是set,保证了内部member的唯一性,另一方面它可以给每个member一个score,代表这个member的排序权重。它内部实现用一种叫跳跃链表的数据结构。

    格式:zadd key [NX|XX] [CH] [INCR] score member [score member ...]

    zadd key1 9.0 member1 8.0 member2 10.0 member3//return 1

    zrevange key1 0 -1 //按score降序排列,参数区间为排名范围 ,相反指令zrange则为升序排列

    zcard key1 //计数

    zrank key1 member1 //查看member1的排名,socre越高返回值越高

    格式:zrangebyscore key min max [WITHSCORES] [LIMIT offset count]

    zrangebyscore key1 0 9 //根据分值区间遍历zset,WITHSCORES同时返回对于score值,LIMIT设置偏移量及返回个数 

3.过期时间

    Redis的所有数据结构都可以设置过期时间,需要注意过期时间是以对象为单位,比如一个hash结构的过期时间是整个hash对象的过期,另外如果设置了过期时间后你调用set方法修改了它,它的过期时间会消失。

    格式:expire key seconds

    expire key1 10  //设置10秒后过期

    ttl key1 //查看对象的过期时间

4.分布式锁

    redis实现分布式锁的原理是在redis里面占一个“坑”,当别的进程也要进来占时,发现已经有人蹲在那里了,就只能放弃或稍后再试。占坑一般使用setnx指令与expire设置过期时间,用完调用del释放这个坑。但是这里有个问题,当逻辑执行到中间出现异常时,可能会导致del指令没有被调用,这样就会陷入死锁,而且还有一个问题,如果在setnx和expire直接服务器进程突然挂掉,也可能会造成死锁。所幸redis在2.8版本作者加入了set的扩展参数,使得setnx与expire可以一起执行。

    另外,也可以使用lua脚本解决一致性问题。

    redis中的lua脚本使用格式如下:

    eval script numkeys key [key ...] arg [arg ...]  //其中script是lua命令,numkeys声明key数量,key列表,参数列表

    EVAL "redis.call('setnx',KEYS[1],ARGV[1]);redis.call('expire',KEYS[1],ARGV[2]);" 1 key1 value1 60   //该语句设置key为key1的过期时间为60秒。

    分布式锁的可重入性:可重入性是指在持有锁的情况下再次请求加锁,如果一个锁支持在同一个线程多次加锁,那么这个锁就是可重入的。比如java语言里的ReentrantLock,redis分布式锁如果需要支持可重入,需要对客户端的set方法进行包装,使用线程ThreadLocal变量存储当前持有锁的value。

redis的分布式锁实现可参考:https://github.com/HZ00M/springboot-demo的RedisWithReentrantLock对象。

5.延时队列

    延时队列一般使用Rabbitmq和kafka中间件实现,相比于专业的消息队列,并没有非常多的高级特性,也没有ack保证,该内容仅作为一项知识点,作为参考。

    redis使用rpush/lpush操作入队,lpop/rpop操作来出队,但是会出现一个问题,如果队列为空,那pop操作将会陷入死循环,拉高客户端CPU和redis的QPS。

    因此,redis提供了blpop/brpop来阻塞读,b就是blocking。另外如果出现空闲连接,一般服务器会主动断开连接,bpop操作会抛出异常来,所有编写客户端时需要注意捕获异常,进行重试。

    延时队列也可以通过zset(有序列表)来实现。可以将消息或对象序列化成一个字符串作为zset的value(可使用fastjson进行序列化),到期时间做为score,然后使用多个线程轮询zset获取到期的任务进行处理,多线程可保证万一一个线程挂了还有其他线程继续处理,因为有多个线程,需要考虑并发争抢任务,保证任务不能被多次执行。redis的zrem方法是多线程争抢任务的关键,它的返回值决定了当前实例有没有抢到任务。(获取到为1,获取不到为0)

redis的延时队列实现可参考:https://github.com/HZ00M/springboot-demo的RedisDelayQueue对象。

6.位图

    介绍:redis提供了位图数据结构(位图不是特殊的数据结构,它的内容其实就是普通的字符串,也就是byte[]数组) ,我们可以使用普通的get/set获取或设置整个位图的内容   redis的位数组是自动扩展,如果设置某个偏移值超出了现有的内容范围,就会自动进行零扩充。

    使用场景:如记录签到信息可大大节省存储空间。

    获取某个字符的ASCII码和二进制数组可用Integer.valueOf(c)和Integer.toBinaryString(c)。

    比如字符‘h’的ASCII码为104,二进制数组为01101000。

    单个bit操作

    格式:setbit key offset value  //按位设值,offset 偏移量 value 0或1

               getbit key offset  //按位取

    如设置'h',其二进制数组2/3/5位为1

    setbit hello 1 1 ;setbit hello 2 1;setbit hello 4 1;  //相当于set hello h

    get hello //返回h(此为整取,也可以使用bitget 命令进行按位取)

    统计与查找:redis提供了位图统计指令bitcount和位图查找指令bitpos,bitcount用于统计指定范围内1的个数,bitpos查找用户从哪一天开始签到,如果指定了范围参数[start,end],就可以统计某个时间范围内签到多少天,但是start和end是字节索引,也就是说指定范围必须是8的倍数。

    bitcount格式:bitcount key [start end]

    set sign hello 

    bitcount sign //返回21

    bitcount 0 1 //前两个字符中1的位数

    bitpos格式:bitpos key bit [start] [end]

    bitpos sign 1 1 1 //从第二个字符算起,第一个1位

    bitpos sign 1 2 2 //从第三个字符算起,第一个1位

    魔术指令bitfield:可以一次进行多次设置(setbit)和获取(getbit),bitfiled有三个子指令,分别是get/set/incrby,它们都可以对为片段进行读写,但是最多只能处理64个连续的位。

    bitfield格式:bitfield key [get type offset] [set type offset value] [incrby type offset increment]

    前面的设置‘h’可改为bitfield hello set u1 1 1 set u1 2 1 set u1 4 1,效果是一样的。

    bitfield hello get u4 0 //从第一位开始取4位,结果是无符号数

    bitfield hello get i4 0  //从第一位开始取4位,结果是有符合数

    所谓的有符号数是位数组中第一位是符号位,剩下的才是值,如第一位是1,那就是负数,有符号位最多可以取64位,无符号数最多可取63位。

    incrby子指令用来对指定范围的位进行自增操作,既然是自增,就有可能溢出,如果增加的是正数,就有可能上溢,增加的是负数,就有可能下溢。如果溢出,就将溢出的符号位丢掉,如果是8位的无符号数255,加一就会溢出,全部变成零。如果有符号位数127加一就会溢出,变成-128。redis提供三个溢出策略,默认是折返(wrap),还可以选择失败不执行,还可以进行饱和截断(sat)

    如:bitfield hellow overflow sat incrby u4 2 1 //从第三位起取4位加1,溢出则保留最大值

7.HyperLogLog

    介绍:HyperLogLog提供不精确的去重技术方案(标准误差0.81%),是redis的高级数据结构。

    使用场景:计算UV(PV是页面访问量,UV是用户量),如使用set存储UV,会很浪费存储空间,因此可以使用内存占用率低的HyperLogLog。

    HyperLogLog格式:pfadd key member (对应sadd)

                                    pfcount key (对应scard)

                                    pfmerge distkey sourcekey [sourcekey ...](用于多个pf计数值得累加)

8.布隆过滤器

    介绍:布隆过滤器可以理解为一个不name精确的set,在redis4.0之后才提供。布隆过滤器有两个基本指令,bf.add添加元素,bf.exists查询元素是否存在,它的用法和set集合的sadd和sismember差不多,注意一次只能添加一个元素,如需添加多个要用到bf.madd,同样查询多个使用bf.mexists。

    bf.add key1 member1

    bf.exists key1 member1 //1存在0不存在

    bf.madd key1 member1 member2 ...

    bf.mexists key1 member1 member2 //返回多个值 1 1 ...

    布隆过滤器有一定的误判性,因此redis还提供了自定义参数的布隆过滤器,需要我们在add之前使用bf.reserve显式创建,bf.reserve有三个参数,分别是key,error_rate和initial_size。错误率越低需要的空间越大,initial_size表示预计的元素数量,当实际数量超出这个数值时,误判率会上升。如不使用bf.reserve,默认的error_rate是0.01,initial_size是100。

    扩展:布隆过滤器在NoSQL领域使用非常广泛,我们平时用到的HBase,Cassandra,LevelDB,RocksDB内部都有布隆过滤器结构。布隆过滤器可以显著降低数据库IO请求数量。

9.限流策略

    redis的限流可使用zset实现,通过score圈出一个时间窗口,窗口外的数据都可以砍掉,而value只要保证唯一性即可,如使用时间戳。

    具体方法:用一个zset结构记录用户的行为历史,每一个行为作为zset中的一个key,同一个用户的同一个行为用一个key记录。通过统计窗口内行为数量与阈值进行比较,就可以得出当前行为是否允许。 

    redis4.0提供了一个限流redis模块,它叫redis-cell,该模块使用了漏斗算法。

    漏桶算法(Leaky Bucket):主要目的是控制数据注入的速率,平滑操作次数。漏桶算法提供了一种机制,通过它,突发流量可以被整形以便提供一个稳定的流量。漏桶算法的示意图如下:

    该模块只有一条指令 cl.throttle

    cl.throttle key1 15 30 60 1 // 15为容量,30/60为速率 ,60秒内30次操作 ,1 quota 多长时间漏斗完全空出来。返回值为【0,15,14,-1,2 】返回值第一个参数0表示允许,1表示拒绝。15表示漏斗容量,14表示剩余容量,第四个参数表示多长时间后可以再试(有空间了),第五个参数表示多长时间后漏斗完全空出来

    上面这条指令的意思是允许key1的操作次数每60秒最多30次,初始容量为15是说一开始连续操作15次后才开始受速率影响,在执行限流指令时,如果被拒绝了,就需要丢弃或重试,可直接用第四个参数的值进行sleep后重试。

10.GeoHash

    GeoHash算法:业界通用的地理位置距离排序算法,算法将二维的经纬度映射到一维数组,这样就将所有的元素都挂载到一条直线上。

    Geo的内部结构实际上就是一个zset结构,score是geohash的52位整数值,value是元素的key通过score排序就可以得到坐标附近的其他元素,并通过score还原成坐标值就可以得到元素的原始坐标。

    Geo有6条指令,格式如下:

    添加元素:geoadd key longtitude latitude member [ longtitue latituemember...]

    计算距离:geodist key member1 member2 [unit]

    获取元素坐标:geopos key member1 [member2 ...]

    获取geohash值:geohash key member1 [member2 ...]

    获取指定元素附近的元素:georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [count value] asc|desc 

    根据坐标值查询附近元素【附近的车】【附近的餐馆】:

    georadius key longtitue latitue radius m|km|ft|mi [withdist] [withhash] [count value] asc|desc

    geo数据如果过大,建议进行拆分,且数据使用单独的redis部署,不使用集群环境。

11.检索

    keys格式:keys pattern     (采用遍历算法,时间复杂度为O(n))

    scan格式:scan cursor [match pattern] [count count] (count不是限定数量,而是限定服务器单次遍历字典槽位的数量,如果游标的返回值不为零,说明遍历还没结束)

    scan采用的是高位进位加法来遍历,高位进位可避免扩容和缩容时槽位的遍历和遗漏。    

    大key扫描:大key扫描是检索redis中的大对象,可在客户端启动时加上--bigkeys,如果担心这个指令会抬升redis的ops,还可增加一个参数 -i 0.1,上面指令的意思是每隔100条scan指令就会休眠0.1s,ops就不会剧烈抬升,但扫描的时间会变长。

12.持久化

    redis的持久化机制有两种,第一种是快照,第二种是aof日志。快照是一次全量备份,aof日志是连续的增量备份。

   快照原理: redis使用操作系统的多进程COW(copy on write)机制来实现快照持久化。redis在持久化时会调用glibc的函数fork产生一个子进程,快照持久化操作完全交给子进程来处理,子进程刚刚产生时,它与父进程共享内存里的代码段和数据段,子进程在做数据持久化时不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,然后序列化到磁盘中。当父进程对数据进行修改时,会将被修改的数据共享页复制一份分离出来,然后对这个复制页面进行修改,随 着越来越多的共享页面的分离,内存会持续增长,但最高不会原数据内存的2倍。快照会丢失大量数据。    

aof原理:aof日志存储的是redis的顺序指令序列,只记录对内存数据进行修改的指令。在redis长期运行过程中,aof会变得越来越长,如果实例宕机重启,aof日志会非常耗时,此时需要对aof日志进行瘦身,redis提供bgrewriteaof 指令对aof日志进行瘦身 。

    Linux的glibc提供了fsync(int fd)函数可以将指定内容强制从内核缓存刷到磁盘,只要redis实时调用fsync函数就可以保证aof日志不丢失。但fsync是一个磁盘io操作,它很慢,如果redis每执行一条指令就要fsync一次,那redis的高性能地位就不保了。redis默认每隔一秒fsync一次,该周期是可配置的,redis另外还提供了两个策略:一个是永不,让操作系统决定合适同步磁盘,很不安全;另外一个是一个指令就fsync一次,但生产环境最好不要使用。可在配置文件中看到这几个配置:

#appendfsync always    

appendfsync everysec

# appendfsync no    

redis4.0混合持久化。原理是redis重启的时候先加载快照内容(.rdb),然后再重放增量aof日志。

13.管道

    管道本质是将多个操作指令由客户端封装成数据包一次性发送给服务端进行批量操作,达到节省io的目的,管道中指令越多,效果越好。

redis自带了压力测试工具redis-benchmark ,使用这个工具可以进行管道测试

    >redis-benchmark -t set -q //返回 set:51452 requests per second

    我们加入管道选项-P参数,它表示单个管道内并行请求的数量,当P=2,QPS可达到9w/s。

14.事务

    redis同样提供了事务机制,有三个指令,分别是multi/exec/discard。multi表示事务开始,exec表示事务执行,discard表示事务丢弃。

    redis的事务失败后,后面的指令还会继续执行,使用redis的事务不具备原子性,只能满足隔离性(当前事务不被其他事务打断的权利)

    redis中的乐观锁:redis提供了watch机制,watch会在事务开始前盯住一个或多个键,当事务执行时,redis会检测关键字自watch之后,是否被修改了(包括当前事务所在的客户端),如果关键字被人动过了,exec就会返回Null,告知客户端事务执行失败,这时客户端可进行重试。

15.主从同步

    分布式理论的基石 --------  CAP原理

        C - Consistent , 一致性

        A - Availability,可用性

        P - Partiton tolerance,分区容忍性

    分布式系统的节点往往都是分布在不同的机器上进行网络隔开的,这意味着必然有网络断开的风险,这个断开的场景叫做网络分区。

    在发送网络分区时,两个分布式节点无法互相通信,我们对一个节点进行修改操作将无法同步到另外一个节点,所以数据的一致性无法得到满足,因为两节点数据不再保持一致,除非我们牺牲可用性,也就是暂停分布式节点服务,在发生网络分区时,不再提供修改数据功能,直到网络恢复。

    最终一致:redis的主从数据是异步同步的,所以分布式的redis不满足一致性要求。当客户端从redis主节点修改了数据后,立即返回,即使在主从网络断开的情况下,主节点依旧可以正常对外提供服务,所以redis满足可用性。从节点在网络恢复后会采用多种策略努力追赶落后的数据。

    主从同步:redis支持主从同步和从从同步。

    增量同步:redis同步的是指令流,主节点会将修改性的指令记录在本地内存buffer中,如何异步的将buffer中的指令记录同步到从节点,从节点一步步执行同步指令达到和主节点一样的状态,同时反馈自己同步到哪里了(偏移量)。redis复制内存buffer是一个定长的环形数组,如果因为网络不好,redis主节点上那先没有同步的指令可能会被后续的指令覆盖,这时候就需要更复杂的同步机制,快照同步。

    快照同步:快照同步是非常消耗资源的操作,它首先会进行一次bgsave(产生.rdb),然后将快照传送到从节点。快照接受完毕后,先清空当前内存,然后执行一次全量加载,加载完成后通知主节点继续进行增量同步。但如果快照时间过长或者复制buffer太小,一样会产生覆盖问题,因此务必配置一个合适的复制buffer大小。

    增加从节点:当从节点刚加入集群时,它必须先进行一次快照同步,完成后才进行增量同步,redis2.8.18版本后快照文件将直接通过套接字传输减少主节点的io操作。

    wait指令:wait指令可以让异步复制变成同步复制,确保强一致性。

    wait格式:wait numslaves timeout //numslave确保多少个从节点同步没有滞后,timeout设置为0表示一直等待。

    配置主从方式::

        1:slaveof指令:从服务器启动后,执行slaveof host port 

        2:配置方式:将

# slaveof <masterip> <masterport>

                            改成

slaveof 127.0.0.1 6379

                                     masterauth redis

    主从复制是系统数据安全的保障,必须认真对待。

16.Sentinel(哨兵模式)

    哨兵模式可以在故障发生时自动进行主从切换,redis提供的redis sentinel可以看成一个zookeeper集群,一般由3~5个节点组成。当客户端连接集群时,首先连接sentinel,通过sentinel来查询主节点地址,然后才进行交互。

    由于redis采用异步复制,无法保证消息完全不丢失,但可以保证消息少丢失。它有两个选项可以限制主从延迟过大。

    min-slaves-to-write 1

    min-slaves-max-lag 10

    第一个参数表示主节点至少有一个从节点在进行正常复制,否则就停止对外写服务。

    何为正常复制,这个参数就是又第二个参数控制的,它的单位是秒,表示如果10秒内没有收到从节点的反馈,意味着同步不正常。

17.一主二从三哨兵模式搭建

    假设有三台服务器,ip分别为    127.1.1.1    ,    127.1.1.2    ,    127.1.1.3:

    主库配置:

        # 1. 修改绑定ip为服务器内网ip地址,做绑定,三台各自填写各自的ip地址

        bind 172.1.1.1

        # 2. 保护模式修改为否,允许远程连接

        protected-mode no

        # 3. 设定密码

        requirepass"123"

        # 4. 设定主库密码与当前库密码同步,保证从库能够提升为主库

        masterauth"123"

        # 5. 打开AOF持久化支持

        appendonly yes

两个从库配置:

        # 1. 绑定的地址

        bind172.1.1.2

        # 2. 保护模式修改为否,允许远程连接

        protected-mode no

        # 3. 设定sentinel myid 每个都不一样 

        sentinel myid 04d9d3fef5508f60498ac014388571e719188527

        # 4. 设定监控地址,为对应的主redis库的内网地址

        sentinel monitor mymaster 172.1.1.1 6379 2

        # 5. 设定5秒内没有响应,说明服务器挂了,需要将配置放在sentinel monitor master 127.0.0.1 6379 1下面

        sentinel down-after-milliseconds mymaster 5000

        # 6. 主数据库密码,需要将配置放在sentinel monitor master 配置下面

        sentinel auth-pass mymaster 123

        # 7. 设定15秒内master没有活起来,就重新选举主

        sentinel failover-timeout mymaster 15000

        # 8. 表示如果master重新选出来后,其它slave节点能同时并行从新master同步缓存的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保定的设置为1,只同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。

        sentinel parallel-syncs mymaster 2

18.消息队列Stream

    介绍:redis5.0提供的一个新的数据结构stream,是一个强大的支持多播的可持久化消息队列,它将所有加入的消息都串起来,每个消息都有一个唯一的ID和对应的内容。消息是持久化的,redis重启之后,内容还在。每个stream都有一个唯一的名称,它就是redis的key,在我们首次使用xadd时自动创建。

    每个stream可以挂多个消费组,每个消费组都有个游标last_delivered_id在stream数组上往前移动,表示当前消费组已经消费到哪条消息了。每个消费组都有一个stream内唯一的名称,消费组不会自动创建,它需要单独的指令xgroup create进行创建需要指定从stream的哪条消息开始消费。这个id用来初始化last_delivered_id变量。

    每个消费组的状态都是相互独立的,也就是说stream内部的消息会被每个消费组消费到。

    同一个消费组可以挂接多个消费者,这些消费者之间是竞争关系,消费者内部有一个pending_ids(Pending Entries List),它记录了当前已经被客户端读取的消息,但是还没有ack,这是一个很核心的数据结构,它用来确保客户端至少消费了一次消息。

    增删查改:

    1.xadd [maxlen len]  key  #|*   key1 value1 [key2 value2 ...]  //追加消息, *和#表示服务器自动生成ID,maxlen提供一个定长,可以将老的消息干掉,确保不会超出指定长度

    2.xdel key  ID //删除消息

    3.xrange  - +  //获取消息列表,会自动过滤已经删除的消息,+ -表示最大值和最小值,也可以指定ID如xrange  -  1482837165811-0

    4.xlen  key  //消息长度,删除操作对长度没有影响

    5.del key   //删除stream

    6.xread count limit streams key ID //从stream头部读取limit 条信息,当使用xread时,可以忽略消费组

        xread block 0 count 1 streams key1 $ //从尾部阻塞等待新消息到来,block 0 表示永远阻塞,block 1000表示阻塞1S,一秒内没有任何消息到来就返回nil;

    创建消费组:

    stream通过xgroup create指令创建消费组,需要传递起始ID。

    xgroup create key1 group1 0-0 //表示从头开始消费

    xgroup create key1 group2 $  //$表示从尾部开始消费,只接受新消息

    xinfo stream key1//获取stream信息

    xinfo groups group1 //获取stream消费组信息

    xreadgroup GROUP group1 comsumer1 count 1 streams key1 > // >表示从当前消费组的last_delivered_id后开始读,每当消费者读取一条消息,last_delivered_id就会前进

    xinfo comsumers key1 group1 # //查看group1每个消费者的状态

    xack key1 group1 ID //确认一条消息 ,待处理消息(peding)变成了4条 

19.查询指令(info)

    info指令显示的信息非常多,分为9大块:

    1.server服务器运行环境参数

    2.clients客户端相关信息

    3.memory服务器运行内存统计信息

    4.persistence持久化信息

    5.stats通用统计数据

    6.replication主从复制相关信息

    7.cpu cpu相关信息

    8.cluster集群信息

    9.keyspace键值对统计数量信息

    info的参数非常多,以下挑选关键性的、且非常实用的参数详解:

 info stats//redis每秒执行多少次指令?

    instantaneous_ops_per_sec:789 //表示所有客户端每秒会发送789条指令到服务器

    info clients //redis连接了多少客户端

    connected_clients:125 //这个就是正在连接的客户端数量

    client list     //可以使用这个指令列出所有客户端的源头

    rejected_connetctions参数表示因为超出连接数限制而被拒绝连接的次数,如果这个数字很大,说明需要调整maxclients参数

 info memory//查看内存信息

    use_memory_human:828.22k  //内存分配器(jemalloc)从操作系统分配的内存总量

    use_memory_rss_human:3.11M  //操作系统看到的内存占用,top命令看到的内存

    use_memory_peak_human:842.11k  //redis内存消耗的峰值

    use_memory_lua_human:21.00k  //lua脚本占用的内存大小

    如果单个redis内存占用过大,需要考虑集群

info replication//查看复制模块信息

    repl_backlog_active:0

    repl_blocklog_size:1048489    //这个就是挤压缓冲区大小

    复制积压缓冲区大小非常重要,它直接影响到主从复制的效率。积压缓冲区是环形的。

    可查看sync_partial_err变量的次数确定是否要扩大积压缓冲区,它表示主从半同步复制失败的次数。

集群方案1(codis)

集群方案2(redisCluster)

上一篇下一篇

猜你喜欢

热点阅读