一站式学习Redis, 从入门到高可用分布式实践-04redis其它功能

04-瑞士军刀redis其它功能

  1. 慢查询
  • 生命周期、两个配置、三个命令、运维经验

  • 生命周期两点说明:
    慢查询发生在第三阶段(执行命令);
    客户端超时不一定是慢查询,但是慢查询是客户端超时的一个可能因素

  • 两个配置:

  • slowlog-max-len:
    先进先出队列、固定长度、保存在内存内

  • slowlog-log-slower-than:
    慢查询阈值(单位:微秒)、
    slowlog-log-slower-than=0,记录所有命令
    slowlog-log-slower-than<0,不记录任何命令

  • 默认值
    config get slowlog-max-len
    config get slowlog-log-slower-than

  • 修改配置文件重启,不建议

  • 动态配置
    config set slowlog-max-len 1000
    config set slowlog-log-slower-than 1000

  • 慢查询命令
    slowlog get [n] 获取慢查询队列
    slowlog len 获取慢查询队列长度
    slowlog reset 清空慢查询队列

  • 运维经验
    slowlog-log-slower-than不要设置过大,默认值是10ms,通常设置1ms
    slowlog-max-len慢查询队列大小,默认值是128
    理解命令的生命周期
    定期持久化慢查询

  1. pipeline
    (1)什么是流水线、客户端时间、与原生操作对比、使用建议
    (2)什么是流水线

    一次pipeline(n条命令) = 一次网络时间+n次命令时间
    (3)流水线的作用
  • reids的命令时间是微秒级别的
  • pipeline每次条数要控制网略
    (4)流水线的作用-续

    (5)流水线pipeline效率比对
import time

import redis

pool = redis.ConnectionPool(host="xxxxx", port=6382, db=1, password="xxxx")
r = redis.Redis(connection_pool=pool)

# 不使用pipeline时
"""
# 计时开始
start = time.time()

for i in range(10000):
    r.hset(f"hashkey:{i}", f"field{i}", f"value{i}")

print(time.time() - start)  # 执行时间312秒
"""

# 使用pipeline时
start = time.time()

for i in range(100):
    pipe = r.pipeline()  # 管道/流水线默认是原子的,也可以关闭transaction=False
    for j in range(100*i, 100*(i+1)):
        pipe.hset(f"hashkey:{j}", f"field{j}", f"value{j}")
    pipe.execute()

print(time.time() - start)  # 执行耗时7s, 比上面不使用pipeline快了40多倍

# 使用pipeline时-2调整每次传输100个命令为1000个命令,效率又显著提高了
start = time.time()

for i in range(10):
    pipe = r.pipeline()  # 管道/流水线默认是原子的,也可以关闭transaction=False
    for j in range(1000*i, 1000*(i+1)):
        pipe.hset(f"hashkey:{j}", f"field{j}", f"value{j}")
    pipe.execute()

print(time.time() - start)  # 执行耗时1s, 比上面不使用pipeline快了300多倍


(6)使用建议

  • 注意每次pipeline携带的数据量
  • pipeline每次只能作用在一个redis节点上
  • M操作与pipeline的区别
  1. 发布订阅
    (1)角色、模型、API、发布订阅与消息队列
    (2)角色:发布者publisher、订阅者subscriber、频道channel
    (3)模型:

    (4)发布订阅角色和模型

    (5)发布订阅API
    publish subscribe unsubscribe 其它
    (6)发布订阅案例
    一个发布者,两个订阅者
  • 两个订阅者
import redis
from threading import Thread, current_thread

pool = redis.ConnectionPool(host="xxxxxx", port=6382, db=0, password="xxxxxx")
r = redis.Redis(connection_pool=pool)


class PubSub(object):
    def __init__(self):
        self.pub = r.pubsub()

    def subscribe(self, *args):
        self.pub.subscribe(*args)
        self.pub.parse_response()
        self.pub.parse_response()
        return self.pub


def subscribe(p):
    while True:
        msg = p.parse_response()
        for i in msg:
            print(current_thread().name, i.decode(encoding="utf8"))


if __name__ == '__main__':

    # 开启一个订阅者
    t1 = Thread(target=subscribe, args=(PubSub().subscribe("my-first-channel", "my-second-channel"),))
    t1.start()

    # 开启第二个订阅者
    t2 = Thread(target=subscribe, args=(PubSub().subscribe("my-first-channel", "my-third-channel"),))
    t2.start()

    # 等待所有子线程结束,主线程在结束
    t1.join()
    t2.join()

  • 一个发布者
import redis

pool = redis.ConnectionPool(host="xxxxxx", port=6382, db=0, password="xxxxx")
r = redis.Redis(connection_pool=pool)

r.publish("my-first-channel", "first:哈哈哈")
r.publish("my-second-channel", "second:嘿嘿嘿")
r.publish("my-third-channel", "third:呵呵呵")
  1. bitmap

  2. HyperLogLog
    (1)新的数据结构
    基于hyperloglog算法:极小空间完成独立数量统计
    本质还是字符串
    (2)三个命令
    pfadd key element [element] 向hyperloglog中添加元素
    pfcount key 计算Hyperloglog独立总数
    pfmerge destkey sourcekey [sourcekey ...] 合并多个hyperloglog
    (3)内存消耗
    (4)使用经验

posted @ 2022-04-11 20:32  专职  阅读(31)  评论(0编辑  收藏  举报