
211工程院校贵州大学管理学院硕士研究生、全国百强城商行资讯科技部五级专技工程师、互联网金融行业资深DevOps研发工程师、金融科技运维自动化平台研发项目经理。曾在国内多家知名互联网公司 平安科技、微众银行、顺丰科技、魅族任职. 具有多年国内一线互联网公司自动化运维平台设计与开发经验。
1
前言
ZSET保留了集合中元素不能重复的特点,但不同的是ZSET中的元素是有顺序的。排序的依据是与每个元素对应的score, 在ZSET中元素不可重复但score可以重复,就好比是一个班级,学生的学号是不相同的,但是考试成绩是可以相同的。如下图所示:
本文以下内容介绍ZSET的几种应用场景与之对应的示例代码在生产中应用需考虑更多细节。
2
排行榜
通过ZSET能实现实时热点排行,如当日最热帖topX。实现思路为将日期作为key, 帖子ID作为有序集合中的元素(member), 帖子每被点击一次就在现有分数(score)的基础上增量一个值,如下图所示:

示例代码如下:
多次执行模拟点击帖子代码,每次模拟点击总量100次,随机点击现有的26个帖子。
#!/usr/bin/pythondate = "2021-06-01 00:00:00"import randomdef topicRead():r = redis.Redis(host="172.16.70.143", port=6379, decode_responses=True, db=0)topic_list = list(set(string.ascii_letters.lower()))for _ in range(100):s = random.choice(topic_list)r.zincrby(date, s, 1)print("Done..")
获取当日最热帖TOP3
#!/usr/bin/pythondate = "2021-06-01 00:00:00"def getRank():w = r.zrevrange(date, 0, 2, withscores=True)print(w)
# 代码输出[('b', 75.0), ('h', 71.0), ('u', 70.0)]
3
访问频次限制
#!/usr/bin/pythonimport redis, timedef access_limits(username, sec, count):timestamp = int(time.time())r = redis.Redis(host="172.16.70.143", port=6379, decode_responses=True, db=0)login_count = r.zcount(username, timestamp-sec, timestamp)if login_count <= count:s = "用户:%s 在%s秒内 已登录%s次..放行.."%(username, sec, login_count)r.zadd(username, '_'.join([username, str(timestamp)]), timestamp) ##登录的时间戳 打一下print(s)else:r.zadd(username, '_'.join([username, str(timestamp)]), timestamp) ##登录的时间戳 打一下s = "用户:%s 在%s秒内 已登录%s次..限制登录.."%(username, sec, login_count)print(s)if __name__ == '__main__':username = '2019020758'access_limits(username, 20, 3)
#代码输出:(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录0次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录1次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录2次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录3次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录4次..限制登录..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录5次..限制登录..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录6次..限制登录..###(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录1次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录2次..放行..(workplace) [root@localhost python]# python demo7.py用户:2019020758 在20秒内 已登录3次..放行..(workplace) [root@localhost python]# python demo7.py
4
延时队列
#!/usr/bin/pythonimport redis, timedef task_producer(task_name, exetime):time_stamp = time.mktime(time.strptime(exetime, "%Y-%m-%d %H:%M:%S"))r = redis.Redis(host="172.16.70.143", port=6379, decode_responses=True, db=0)r.zadd("task_list", task_name, time_stamp)s = "任务%s加入队列成功, 执行时间%s"%(task_name, time_stamp)print(s)def callback(x):print("正在执行回调函数..")print(x)print("回调函数执行完成.....")def task_consumer(callback):r = redis.Redis(host="172.16.70.143", port=6379, decode_responses=True, db=0)while 1:timestamp = int(time.time())print("当前时间: %s" %timestamp)w = r.zrevrangebyscore("task_list", timestamp, 0, withscores=True)## 执行任务 成功后删除任务for j in w:print(j, '11111')callback(j[0])r.zrem("task_list", j[0])print("已删除任务%s_%s"%("task_list", j[0]))time.sleep(2)if __name__ == '__main__':task_producer("hello1", "2021-06-01 18:45:21")task_producer("hello2", "2021-06-01 18:45:34")task_producer("hello3", "2021-06-01 18:45:46")task_consumer(callback=callback)
代码输出:任务hello1加入队列成功, 执行时间1622587521.0任务hello2加入队列成功, 执行时间1622587534.0任务hello3加入队列成功, 执行时间1622587546.0当前时间: 1622587524('hello1', 1622587521.0) 11111正在执行回调函数..hello1回调函数执行完成.....已删除任务task_list_hello1当前时间: 1622587526当前时间: 1622587528当前时间: 1622587530当前时间: 1622587532当前时间: 1622587534('hello2', 1622587534.0) 11111正在执行回调函数..hello2回调函数执行完成.....已删除任务task_list_hello2当前时间: 1622587536当前时间: 1622587538当前时间: 1622587540当前时间: 1622587542当前时间: 1622587544当前时间: 1622587546('hello3', 1622587546.0) 11111正在执行回调函数..hello3回调函数执行完成.....已删除任务task_list_hello3当前时间: 1622587548
5
结束语


文章转载自稻壳编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




