当前位置:首页 >娱乐 >这个使用场景,Etcd 比 Redis 强 我认为 etcd 做得更好

这个使用场景,Etcd 比 Redis 强 我认为 etcd 做得更好

2024-07-01 09:39:26 [百科] 来源:避面尹邢网

这个使用场景,个使Etcd 比 Redis 用场强

作者:kingname 存储 存储软件 Redis Redis 非常强大,我出版过一本书专门介绍 Redis 个使的各种用法。但这并不是用场说 Redis 在各种方面都没有对手。至少在分布式系统的个使配置更新这个场景上面,我认为 etcd 做得更好。用场

[[437980]]

我们说,个使要评判一个东西的用场好坏,一定要说明具体在什么业务场景。个使脱离业务谈好坏是用场没有意义的。

这个使用场景,Etcd 比 Redis 强 我认为 etcd 做得更好

Redis 个使非常强大,我出版过一本书专门介绍 Redis 用场的各种用法。但这并不是个使说 Redis 在各种方面都没有对手。至少在分布式系统的用场配置更新这个场景上面,我认为 etcd 做得更好。个使

这个使用场景,Etcd 比 Redis 强 我认为 etcd 做得更好

要解释这个问题,我们来看一个具体的业务场景:

这个使用场景,Etcd 比 Redis 强 我认为 etcd 做得更好

在 Redis 中有一个列表 sentence,里面会源源不断地写入字符串。现在我有一个过滤程序:trash_filter.py,它一条一条从 Redis 读取数据,判断字符串中是否有特定的关键词,如果有,那么直接丢弃。如果没有,那么把数据存入 MongoDB。

这个场景非常简单,于是你很快就写出了一个 Python 程序:

  1. import redis 
  2.  
  3.  
  4. class TrashFilter: 
  5.     def __init__(self): 
  6.         self.client = redis.Redis() 
  7.         self.trash_words = ['垃圾'] 
  8.  
  9.     def read_data(self): 
  10.         while True: 
  11.             data = self.client.lpop('sentence') 
  12.             if not data: 
  13.                 return  
  14.             yield data.decode() 
  15.  
  16.     def do_filter(self): 
  17.         for sentence in self.read_data(): 
  18.             for word in self.trash_words: 
  19.                 if word in sentence: 
  20.                     break 
  21.             else: 
  22.                 self.save_sentence(sentence) 
  23.  
  24.     def save_sentence(self, sentence): 
  25.         print('进行后续保存 sentence 的操作:', sentence) 
  26.  
  27.  
  28. if __name__ == '__main__': 
  29.     trash_filter = TrashFilter() 
  30.     trash_filter.do_filter() 

在上面的代码中,需要过滤的词是以列表的形式直接写到代码里面的。那么问题来了,如果这些过滤词是动态改变的怎么办?每次为了修改这些词,你都需要重启一下这个程序吗?

可能有同学提到,可以把这些词存放到数据库里面,每次从数据库里面读取就可以了。Redis 本身就是一个 Key-Value 数据库,可以直接使用 Redis 的字符串来存放:

  1. def do_filter(self): 
  2.     for sentence in self.read_data(): 
  3.         for word in self.client.get('trash_words').decode().split(','): 
  4.             if word in sentence: 
  5.                 break 
  6.         else: 
  7.             self.save_sentence(sentence) 

把所有的过滤词以英文逗号分割组成长字符串,储存到Redis 中名为trash_words的字符串里。每读取到一个句子,都从 Redis 里面再次读取这个过滤词列表,然后进行检查。

这样做,实时性确实得到了保障,每次只要trash_word字符串一发生修改,程序立刻就能获取到最新的过滤词。

但这样做有一个问题——每次读取trash_words是需要请求网络的,而网络 IO 是非常费时间的。

那么我们是不是可以每5分钟获取一次最新的trash_words呢?当然也可以,我在文章:一日一技:实现有过期时间的LRU缓存中介绍过如何实现一个带有过期时间的 LRU 缓存。

这样做,速度确实提高了,但是实时性又降低了。

如果读者对 Redis 比较熟悉,当然也可以使用 Lua 脚本或者 Redis 的Pipeline 实现在一次请求里面同时获取一条句子并拿到过滤词列表,或者使用 Monitor 命令监控 Key 的变化。但代码写起来会比较复杂。

有没有又快又简单还稳定的解决方案呢?答案是有,那就是使用 etcd.

etcd 的官网写着这样一句话:

A distributed, reliable key-value store for the most critical data of a distributed system.

用于分布式系统最关键数据的分布式、可靠的键值储存。

etcd 本来就是为了分布式系统而生的,它专注于键值储存。初看起来,相当于只是 Redis 的字符串功能,但却比 Redis 的字符串更为强大。

我们可以监控 etcd 中的一个键,当它发生变化的时候,就调用我们提前定义好的函数。

在 Ubuntu 中,可以使用 apt-get 安装 etcd,在 macOS 中,可以使用 homebrew 安装 etcd。当然 etcd 也有已经编译好的可执行文件,可以从Releases · etcd-io/etcd · GitHub[1]下载下来直接运行就能启动一个单节点的 etcd 服务。

启动服务以后,我们再来安装一个Python 库,用来操作 etcd:

  1. pip install etcd3 

Python 读写 etcd 非常简单:

  1. import etcd3 
  2.  
  3. client = etcd3.client() 
  4. client.put('key', value) # 添加数据 
  5. value, kv_meta = client.get('key') # 读取数据,返回的数据value 是 bytes 型数据 

而我们要用的,是 etcd 的watch功能。我们先写一段简单的代码来说明 watch的功能:

  1. import etcd3 
  2. import time 
  3.  
  4.  
  5. def callback(response): 
  6.     for event in response.events: 
  7.         print(f'Key: { event.key}发生改变!新的值是:{ event.value}') 
  8.  
  9.  
  10. client = etcd3.client() 
  11. client.add_watch_callback('test', callback) 
  12.  
  13. for i in range(100): 
  14.     print(i) 
  15.     time.sleep(1) 

正常情况下,这个程序会打印从0到99,每秒打印一个数字。但是当我们中途修改了 etcd 中,名为test这个 key 的值以后,我们发现回调函数被运行了,如下图所示:

可以看到,etcd 监控一个 key 是否变化,它不像 Redis 的blpop这样阻塞式地监控,而是在后台监控,当key 的值发生了改变时,触发一个事件,调用回调函数。所以整个监控的过程不会干预我们自己程序的正常运行。

在一般情况下,传入回调函数的response 对象,它的.events属性是只有一个元素的列表。但如果这个 key 在极短时间内变化了很多次,那么这个列表里面可能有多个值。

回到最开始需要解决的问题,我们引入 etcd 以后,困难轻轻松松就被解决了:

通过增加方框框住的update_trash_words方法,并把它作为监控trash_words这个Key 变化事件的回调函数,一旦这个 Key 发生了变化,就会调用回调函数,从而更新self.trash_words这个属性。

运行效果如下图所示:

可以看到,在红线上面,我是有脏数据的句子是不被过滤的,此时脏字也不是过滤词。但是当我们在命令行里面更新了 etcd,把新的过滤词改成垃圾,脏以后,就到了红线下面,我是有脏数据的句子就会被过滤了。

这样就做到了同时兼顾时效性和速度,避免了无效的网络请求。

参考文献

[1] Releases · etcd-io/etcd · GitHub: https://github.com/etcd-io/etcd/releases

本文转载自微信公众号「未闻Code」,可以通过以下二维码关注。转载本文请联系未闻Code公众号。

 

责任编辑:武晓燕 来源: 未闻Code EtcdRedis场景

(责任编辑:综合)

    推荐文章
    • 爱美客(300896.SZ)年报推10转8派35元 除权除息日为2021年3月16日

      爱美客(300896.SZ)年报推10转8派35元 除权除息日为2021年3月16日爱美客(300896.SZ)披露2020年度分红派息、转增股本实施公告,此次实施的利润分配及资本公积金转增股本方案以公司现有的总股本1.202亿股为基数,向全体股东每10股派发35.00元人民币现金( ...[详细]
    • 酷派新机开始预热:前小米产品经理打造

      酷派新机开始预热:前小米产品经理打造老牌国产手机厂商酷派这两天在官方微博带来预热,给出各种暗示称即将发布新机。酷派手机发微博称:“#一派新机# 单扬声器、“假”双扬声器,缺了一半,精彩不止减半。真正的「对称式」双扬声器,该归位了!”“# ...[详细]
    • 微软暗示Xbox移动游戏商城将于2024年上线

      微软暗示Xbox移动游戏商城将于2024年上线微软游戏总裁Spencer表示公司计划的移动游戏商城可能在2024年上线。在接受金融时报采访时,Spencer重申计划在iOS和安卓设备上推出一个Xbox品牌App商城,他解释说微软已经准备好了这个手 ...[详细]
    • 2699元起 荣耀60系列发布:全球首发骁龙778G+

      2699元起 荣耀60系列发布:全球首发骁龙778G+昨天晚间消息,荣耀举行新品发布会,旗下新机荣耀60系列正式亮相,分别为荣耀60和荣耀60 Pro。外形方面,两款新机正面均为居中挖孔屏形态,其中标准版为双曲面屏、Pro为四曲面屏,背面为双圆环相机布局 ...[详细]
    • 2022年北京45个重点文旅项目引资 投资机构反响热烈

      2022年北京45个重点文旅项目引资 投资机构反响热烈在文旅逐渐复苏的大背景下,北京重点文旅项目的投融资情况也备受关注。11月24日,由北京市文化和旅游局主办,北京产权交易所、北京文旅资源交易平台承办的“2022年北京文旅重点项目投融资推介会 ...[详细]
    • 大连市开展旅游市场信用品牌企业信用自律承诺公示

      大连市开展旅游市场信用品牌企业信用自律承诺公示 近期,为进一步推进文化和旅游部文化和旅游市场信用经济发展试点工作,引导全市文化和旅游行业践行诚信经营、守信承诺,大连市首批旅游市场信用品牌企业已自愿签署《大连市文化和旅游企业信用自律承诺书》,承诺 ...[详细]
    • 草原盛会那达慕

      草原盛会那达慕草原盛会那达慕----锡林郭勒千里草原风景大道自驾嘉年华侧记 为了提升锡林郭勒旅游品牌的知名度和影响力,把草原旅游由单一的夏季旅游向反季节旅游、四季旅游推进;同时也为了吸引京津冀地区的自驾游客, ...[详细]
    • 《小小梦魇》开发商公布新图 或暗示新作即将公布

      《小小梦魇》开发商公布新图 或暗示新作即将公布《小小梦魇》开发商Tarsier今日在推特上公布了一张新图,并配文“New world. Emphasis on new”新世界、新事物),或许在暗示一款新作即将公开。《小小梦魇》自发售以来得到了众多 ...[详细]
    • 拼多多先用后付最多能拖几天 若超过15天还能拖几天?

      拼多多先用后付最多能拖几天 若超过15天还能拖几天?拼多多先用后付,顾名思义,就是购买的商品可以先使用,满意再付款,那么先用后付这个过程肯定存在一定的时间周期,不然就没多少意义了,反正顾客提前付款了也可以退货,是一样的道理。那么,拼多多先用后付最多能拖 ...[详细]
    • 九牧王再度惊艳巴黎时装周 匠心打造东方男裤美学

      九牧王再度惊艳巴黎时装周 匠心打造东方男裤美学北京时间2022年1月22日16:00.九牧王以“盛世中华”为灵感,在巴黎时装周掀起一场男裤国潮风尚,宝相花、唐卷草、唐三彩、蓝斑彩等中国唐代元素交织成一幅幅历史画卷拓印在九牧王男裤上,向人们娓娓道来 ...[详细]
    热点阅读