• Redis 入门到分布式 (四) 瑞士军刀Redis其他功能


    个人博客网:https://wushaopei.github.io/    (你想要这里多有)

    目录:

    •           慢查询
    •           Pipeline
    •           发布订阅
    •           Bitmap(位图)
    •           HyperLogLog
    •           GEO

    一、慢查询

    1、慢查询:

        生命周期
        三个命令
        两个配置
        运维经验

    2、生命周期图解:

    两点说明:

    1. 慢查询发生在第3阶段 (如:keys *)
    2. 客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素

    两个配置: -slowlog-max-len

    1. 慢查询是一个先进先出队列
    2. 队列是固定长度的
    3. Redis是保存在内存内

    slowlog list 是慢查询的集合;

    slowlog-max-len 是慢查询的长度或者数量,如图,慢查询从slowlog100到slowlog1以队列形式排列入列;

    两个配置 —— slowlog-log-slower-than

    1. 慢查询阈值(单位:微秒)
    2. Slowlog-log-slower-than=0,记录所有命令
    3. Slowlog-log-slower-than<0,不记录任何命令

    3、配置方法

     1) 默认值

            config get slowlog-max-len = 128

            config get slowlog-log-slower-than = 10000

    2) 修改配置文件重启

    3) 动态配置

            config set slowlog-max-len 1000

            config set slowlog-log-slower-than 1000

    4、慢查询命令:

       1) slowlog get [n] : 获取慢查询队列

      2)slowlog len : 获取慢查询队列长度

      3)slowlog reset : 清空慢查询队列

    5、慢查询运维经验:

      1) slowlog-max-len 不要设置过大,默认10ms,通常设置1ms

      2)   slowlog-log-slower-than 不要设置过小,通常设置1000左右

      3)理解命令生命周期

      4)定期持久化慢查询

    二、pipeline

            什么是流水线?
            客户端实现
            与原生操作对比
            使用建议

    1次网络命令通信模型

    如图,经历了   1次时间 = 1次网络时间 + 1次命令时间

    批量网络命令通信模型

    如图,经历了 n次时间 = n次网络时间 + n次命令时间

    1、什么是流水线?

    如图,经历了 1次pipeline(n条命令) = 1次网络时间 + n次命令时间,这大大减少了网络时间的开销,这就是流水线。

    2、流水线的作用

    两点注意:

    1. redis的命令时间是微秒级别
    2. pipeline每次条数要控制(网络)

    3、案例展示——从北京到上海的一条命令的生命周期有多长?

    由图可知,执行一条命令在redis端可能需要几百微秒,而在网络光纤中传输只花费了13毫秒。假如在执行批量操作而没有使用pipeline功能,会将大量的时间耗费在每一次网络传输的过程上;而使用pipeline后,只需要经过一次网络传输,然后批量在redis端进行命令操作。这会大大提高了效率。

    4、pipeline-Jedis实现?

    首先,引入jedis依赖包:

                	<dependency>
    			<groupId>redis.clients</groupId>
    			<artifactId>jedis</artifactId>
    			<version>2.9.0</version>
                            <type>jar</type>
                            <scope>compile</scope>
    		</dependency>
        

    演示:

    1) 没有pipeline的命令执行:

        Jedis jedis - new Jedis("127.0.0.1",6379);
        for ( int i = 0 ; i < 10000 ; i ++ ){
            jedis.hset("hashkey:" + i , "field" + i , "value" + i);
        }

    假设,在不使用pipeline的情况下,使用for循环进行每次一条命令的执行操作,耗费的时间可能达到 1w 条插入命令的耗时为50s。

    2) 使用pipeline:

            Jedis jedis = new Jedis("127.0.0.1",6379);
            for ( int i = 0; i < 100 ; i++) {
                Pipeline pipeline = jedis.ppipelined();
                for (int j = i * 100 ; j < (i + 1) * 100 ; j++) {
                    pipeline.hset("hashkey:" + j,"field" + j, "value" + j);
                }
                pipeline.syncAndReturnAll();
            }

    假设使用了pipeline 进行批量操作,每次传输100条命令到redis端进行执行操作,大概 1w插入条命令需耗时 0.7s

    3)与原生M操作?

    在原生的redis命令操作中,命令的执行是依次按入列的顺序一条一条执行,具有原子性。

    在使用pipeline进行批量操作后,会将大量命令用pipeline 包装起来,一次性发送到服务端,然后在服务端进行拆分成多个基本命令,此时命令的执行次序是不一定的,因此是非原子性的。

    但,命令执行结果的返回是有序的。

    5、使用建议

     1) 注意每次pipeline 携带数据量

     2) pipeline每次只能作用在一个Redis节点上

     3)M操作与pipeline区别

    三、发布订阅

        角色
        模型
        API
        发布订阅与消息队列

    1、角色:

            发布者
    
            频道
    
            订阅者

    2、模型:

    发布者发布一条消息,订阅者如果订阅了这个频道就可以收到这条消息。

    注意:所有的订阅者都能够收到消息。并且一个订阅者可以订阅不同的频道。

    订阅者无法获取到未订阅前已发布的消息,即无法对已发布消息尽心追击。

    3、API

            1.Publish

            2.Subscribe

            3.Unsubscribe

            4.其他

    1)publish (发布命令)

    2)subcribe(订阅)

    3)unsubcribe(取消订阅)

    4)其他API:

     

    4、消息队列:

    Redis中并没有消息队列这一功能,它对消息队列的实现是通过List发布数据后利用阻塞的机制,将发布的消息如图中的hellojava到服务端,由客户端进行抢夺,客户端拿到后原来的值发生删改的变化来实现的。

    5、发布订阅总结:

    1. 发布订阅模式中的角色
    2. 重要的API
    3. 发布订阅和消息队列的使用场景

    四、 bitmap(位图)

            位图
    
            相关命令
    
            独立用户统计

    1、什么是位图?

                              字符串big 对应的二进制

    如上图,位图将字符串以对应二进制进行存储。

    位图的最大意义在于能够直接去操作redis中的value进行转换后的二进制码,即01100....等。

    2、API : 位图偏移设置—— setbit

    演示:

    127.0.0.1:6379> setbit unique:users:2016-04-05 0 1
    (integer) 0
    127.0.0.1:6379> setbit unique:users:2016-04-05 5 1
    (integer) 0
    127.0.0.1:6379> setbit unique:users:2016-04-05 11 1
    (integer) 0
    127.0.0.1:6379> setbit unique:users:2016-04-05 15 1
    (integer) 0
    127.0.0.1:6379> setbit unique:users:2016-04-05 19 1
    (integer) 0

    演示效果图:

    以上设置一个以unique:users:2016-04-05为key的数据,这里由于没有对该key的value进行初始化设置,默认每一次的setbit操作会在对应的二进制中指定的索引位置插入1,而为声明部分默认为0;即索引为0、5、11、15、19的位置值为1,其他索引位置值为0.

    3、API : 位图偏移范围值获取——bitcount

    演示:

    127.0.0.1:6379> bitcount unique:users:2016-04-05
    (integer) 5
    127.0.0.1:6379> bitcount unique:users:2016-04-05 1 3
    (integer) 3

    上图中,key为unique:users:2016-04-05的位图长度为5,其中偏移量从1到3的值长度为3.

    4、API : 位图区间交互——bitop:

    演示:

    127.0.0.1:6379> bitop and unique:users:and:2016_04_04-2016_04_05 unique:users:2016-04-05 unique:users:2016-04-04
    (integer) 3
    127.0.0.1:6379> bitcount unique:users:and:2016_04_04-2016_04_05
    (integer) 0

    5、API : 获取位图指定值的偏移坐标——bitpos

    注意,返回的位的位置始终是从0开始的,即使使用了start来指定了一个开始字节也是这样。

    演示:

    127.0.0.1:6379> bitpos unique:users:2016-04-04 1
    (integer) 1
    127.0.0.1:6379> bitpos unique:users:2016-04-04 0 1 2
    (integer) 8

    6、独立用户统计:

    1. 使用set 和Bitmap
    2. 1亿用户,5千万独立

    使用经验:

    1. type = string , 最大512MB
    2. 注意setbit时的偏移量,可能有较大耗时
    3. 位图不是绝对好

    五、 hyperloglog

            新的数据结构
            内存消耗
            三个命令
            使用经验

    1、基于HyperLogLog算法:

               绩效空间完成独立数量统计。

    2、本质还是字符串

    127.0.0.1:6379> type hyperloglog_key
    string

    3、三个API命令:

    1) pfadd key element [element ...] :向hyperloglog添加元素

    2)pfcount key [key ...] : 计算hyperloglog的独立总数

    3)pfmerge destkey sourcekey [sourcekey ...] : 合并多个hyperloglog

    使用方法:

    1) Demo演示:

    127.0.0.1:6379> pfadd 2017_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
    (integer) 1
    127.0.0.1:6379> pfcount 2017_03_06:unique:ids
    (integer) 4
    127.0.0.1:6379> pfadd 2017_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-90"
    (integer) 1
    127.0.0.1:6379> pfcount 2017_03_06:unique:ids
    (integer) 5

       ①向id添加四个独立元素,返回结果为1

       ②查看独立元素为4个;

       ③再添加四个独立元素,其中三个重复,一个新的,返回1

       ④查询独立元素为5个,说明独立元素不可重复。

    2) 模拟—— 两个key的八个独立用户的统计合并:

    127.0.0.1:6379> pfadd 2016_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
    (integer) 1
    127.0.0.1:6379> pfcount 2016_03_06:unique:ids
    (integer) 4
    127.0.0.1:6379> pfadd 2016_03_05:unique:ids "uuid-4" "uuid-5" "uuid-6" "uuid-7"
    (integer) 1
    127.0.0.1:6379> pfcount 2016_03_05:unique:ids
    (integer) 4
    127.0.0.1:6379> pfmerge 2016_03_05_06:unique:ids 2016_03_05:unique:ids 2016_03_06:unique:ids
    OK
    127.0.0.1:6379> pfcount 2016_03_05_06:unique:ids
    (integer) 7

    4、统计:内存消耗(百万独立用户):

            ①定义一个key;

            ②声明一个百万次的for循环

            ③拼接1000次元素;

            ④拼接满1000次,执行一次独立元素的插入

            ⑤清空element 临时变量

    性能展示:

    5、使用经验:

    1) 是否能容忍错误?(错误率: 0.81%)

    127.0.0.1:6379> pfcount 2016_05_01:unique:ids(integer)
    1009838
    

    2) 是否需要单条数据

    六、geo

    1、GEO是什么

    以计算5个城市经纬度为例:

    GEO(地理信息定位):存储经纬度,计算两地距离,范围计算等

    2、API: geoadd

    演示:

    127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
    (integer) 1
    127.0.0.1:6379> geoadd cities:locations 116.28 39.55 beijing
    (integer) 0
    127.0.0.1:6379> geoadd cities:locations 117.12 39.08 tianjin 114.29 38.02 shijianzhuang 118.01 39.38 tangshan 115.29 38.51 baoding
    (integer) 4
    

    3、API——geopos:

    演示:

    127.0.0.1:6379> geopos cities:locations tianjin
    1) 1) "117.12000042200088501"
       2) "39.0800000535766543"
    

    4、API——geodist

    演示:

    127.0.0.1:6379> geodist cities:locations tianjin beijing km
    "87.3054"
    

    5、复杂API——georadius

    演示

    127.0.0.1:6379> georadiusbymember cities:locations beijing 150 km
    1) "beijing"
    2) "tianjin"
    3) "tangshan"
    4) "baoding"
    

    6、相关说明:

     1) since 3.2+

     2) type geoKey = zset

     3) 没有删除API: zrem key member

  • 相关阅读:
    毕设2020.02.02
    架构师眼中的高并发架构
    云时代架构读后感二
    以《淘宝网》为例,描述质量属性六个常见场景
    《架构漫谈》读后感
    云时代架构读后感一
    暑假周总结报告08
    暑假周总结报告07
    暑假周总结报告06
    假期周总结报告05
  • 原文地址:https://www.cnblogs.com/wushaopei/p/11979110.html
Copyright © 2020-2023  润新知