示例:数据库取样程序

在使用 Redis 的过程中,我们可能会想要知道 Redis 数据库中各种键的类型分布状况:比如说,我们可能会想要知道数据库里面有多少个字符串键、有多少个列表键、有多少个散列键,以及这些键在数据库键的总数量中占多少个百分比。

代码清单 11-2 展示了一个能够计算出以上信息的数据库取样程序。DbSampler 程序会对数据库进行迭代,使用 TYPE 命令获取被迭代键的类型并对不同类型的键实施计数,最终在迭代完整个数据库之后,打印出相应的取样结果。


代码清单 11-2 数据库取样程序:/database/db_sampler.py

  1. def type_sample_result(type_name, type_counter, db_size):
  2. result = "{0}: {1} keys, {2}% of the total."
  3. return result.format(type_name, type_counter, type_counter*100.0/db_size)
  4.  
  5. class DbSampler:
  6.  
  7. def __init__(self, client):
  8. self.client = client
  9.  
  10. def sample(self):
  11. # 键类型计数器
  12. type_counter = {
  13. "string": 0,
  14. "list": 0,
  15. "hash": 0,
  16. "set": 0,
  17. "zset": 0,
  18. "stream": 0,
  19. }
  20.  
  21. # 遍历整个数据库
  22. for key in self.client.scan_iter():
  23. # 获取键的类型
  24. type = self.client.type(key)
  25. # 对相应的类型计数器执行加一操作
  26. type_counter[type] += 1
  27.  
  28. # 获取数据库大小
  29. db_size = self.client.dbsize()
  30.  
  31. # 打印结果
  32. print("Sampled {0} keys.".format(db_size))
  33. print(type_sample_result("String", type_counter["string"], db_size))
  34. print(type_sample_result("List", type_counter["list"], db_size))
  35. print(type_sample_result("Hash", type_counter["hash"], db_size))
  36. print(type_sample_result("Set", type_counter["set"], db_size))
  37. print(type_sample_result("SortedSet", type_counter["zset"], db_size))
  38. print(type_sample_result("Stream", type_counter["stream"], db_size))

以下代码展示了这个数据库取样程序的使用方法:

  1. >>> from redis import Redis
  2. >>> from create_random_type_keys import create_random_type_keys
  3. >>> from db_sampler import DbSampler
  4. >>> client = Redis(decode_responses=True)
  5. >>> create_random_type_keys(client, 1000) # 创建 1000 个类型随机的键
  6. >>> sampler = DbSampler(client)
  7. >>> sampler.sample()
  8. Sampled 1000 keys.
  9. String: 179 keys, 17.9% of the total.
  10. List: 155 keys, 15.5% of the total.
  11. Hash: 172 keys, 17.2% of the total.
  12. Set: 165 keys, 16.5% of the total.
  13. SortedSet: 161 keys, 16.1% of the total.
  14. Stream: 168 keys, 16.8% of the total.

可以看到,取样程序遍历了数据库中的一千个键,然后打印出了不同类型键的具体数量以及它们在整个数据库中所占的百分比。

为了演示方便,上面的代码使用了 create_random_type_keys() 函数来创建出指定数量的类型随机键,代码清单 11-3 展示了这个函数的具体定义。


代码清单 11-3 随机键生成程序:/database/create_random_type_keys.py

  1. import random
  2.  
  3. def create_random_type_keys(client, number):
  4. """
  5. 在数据库中创建指定数量的类型随机键。
  6. """
  7. for i in range(number):
  8. # 构建键名
  9. key = "key:{0}".format(i)
  10. # 从六个键创建函数中随机选择一个
  11. create_key_func = random.choice([
  12. create_string,
  13. create_hash,
  14. create_list,
  15. create_set,
  16. create_zset,
  17. create_stream
  18. ])
  19. # 实际地创建键
  20. create_key_func(client, key)
  21.  
  22. def create_string(client, key):
  23. client.set(key, "")
  24.  
  25. def create_hash(client, key):
  26. client.hset(key, "", "")
  27.  
  28. def create_list(client, key):
  29. client.rpush(key, "")
  30.  
  31. def create_set(client, key):
  32. client.sadd(key, "")
  33.  
  34. def create_zset(client, key):
  35. client.zadd(key, {"":0})
  36.  
  37. def create_stream(client, key):
  38. client.xadd(key, {"":""})