偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

這個使用場景,Etcd 比 Redis 強

存儲 存儲軟件 Redis
Redis 非常強大,我出版過一本書專門介紹 Redis 的各種用法。但這并不是說 Redis 在各種方面都沒有對手。至少在分布式系統(tǒng)的配置更新這個場景上面,我認為 etcd 做得更好。

[[437980]]

我們說,要評判一個東西的好壞,一定要說明具體在什么業(yè)務(wù)場景。脫離業(yè)務(wù)談好壞是沒有意義的。

Redis 非常強大,我出版過一本書專門介紹 Redis 的各種用法。但這并不是說 Redis 在各種方面都沒有對手。至少在分布式系統(tǒng)的配置更新這個場景上面,我認為 etcd 做得更好。

要解釋這個問題,我們來看一個具體的業(yè)務(wù)場景:

在 Redis 中有一個列表 sentence,里面會源源不斷地寫入字符串?,F(xiàn)在我有一個過濾程序:trash_filter.py,它一條一條從 Redis 讀取數(shù)據(jù),判斷字符串中是否有特定的關(guān)鍵詞,如果有,那么直接丟棄。如果沒有,那么把數(shù)據(jù)存入 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('進行后續(xù)保存 sentence 的操作:', sentence) 
  26.  
  27.  
  28. if __name__ == '__main__'
  29.     trash_filter = TrashFilter() 
  30.     trash_filter.do_filter() 

在上面的代碼中,需要過濾的詞是以列表的形式直接寫到代碼里面的。那么問題來了,如果這些過濾詞是動態(tài)改變的怎么辦?每次為了修改這些詞,你都需要重啟一下這個程序嗎?

可能有同學(xué)提到,可以把這些詞存放到數(shù)據(jù)庫里面,每次從數(shù)據(jù)庫里面讀取就可以了。Redis 本身就是一個 Key-Value 數(shù)據(jù)庫,可以直接使用 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字符串一發(fā)生修改,程序立刻就能獲取到最新的過濾詞。

但這樣做有一個問題——每次讀取trash_words是需要請求網(wǎng)絡(luò)的,而網(wǎng)絡(luò) IO 是非常費時間的。

那么我們是不是可以每5分鐘獲取一次最新的trash_words呢?當然也可以,我在文章:一日一技:實現(xiàn)有過期時間的LRU緩存中介紹過如何實現(xiàn)一個帶有過期時間的 LRU 緩存。

這樣做,速度確實提高了,但是實時性又降低了。

如果讀者對 Redis 比較熟悉,當然也可以使用 Lua 腳本或者 Redis 的Pipeline 實現(xiàn)在一次請求里面同時獲取一條句子并拿到過濾詞列表,或者使用 Monitor 命令監(jiān)控 Key 的變化。但代碼寫起來會比較復(fù)雜。

有沒有又快又簡單還穩(wěn)定的解決方案呢?答案是有,那就是使用 etcd.

etcd 的官網(wǎng)寫著這樣一句話:

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

用于分布式系統(tǒng)最關(guān)鍵數(shù)據(jù)的分布式、可靠的鍵值儲存。

etcd 本來就是為了分布式系統(tǒng)而生的,它專注于鍵值儲存。初看起來,相當于只是 Redis 的字符串功能,但卻比 Redis 的字符串更為強大。

我們可以監(jiān)控 etcd 中的一個鍵,當它發(fā)生變化的時候,就調(diào)用我們提前定義好的函數(shù)。

在 Ubuntu 中,可以使用 apt-get 安裝 etcd,在 macOS 中,可以使用 homebrew 安裝 etcd。當然 etcd 也有已經(jīng)編譯好的可執(zhí)行文件,可以從Releases · etcd-io/etcd · GitHub[1]下載下來直接運行就能啟動一個單節(jié)點的 etcd 服務(wù)。

啟動服務(wù)以后,我們再來安裝一個Python 庫,用來操作 etcd:

  1. pip install etcd3 

Python 讀寫 etcd 非常簡單:

  1. import etcd3 
  2.  
  3. client = etcd3.client() 
  4. client.put('key', value) # 添加數(shù)據(jù) 
  5. value, kv_meta = client.get('key') # 讀取數(shù)據(jù),返回的數(shù)據(jù)value 是 bytes 型數(shù)據(jù) 

而我們要用的,是 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}發(fā)生改變!新的值是:{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,每秒打印一個數(shù)字。但是當我們中途修改了 etcd 中,名為test這個 key 的值以后,我們發(fā)現(xiàn)回調(diào)函數(shù)被運行了,如下圖所示:

可以看到,etcd 監(jiān)控一個 key 是否變化,它不像 Redis 的blpop這樣阻塞式地監(jiān)控,而是在后臺監(jiān)控,當key 的值發(fā)生了改變時,觸發(fā)一個事件,調(diào)用回調(diào)函數(shù)。所以整個監(jiān)控的過程不會干預(yù)我們自己程序的正常運行。

在一般情況下,傳入回調(diào)函數(shù)的response 對象,它的.events屬性是只有一個元素的列表。但如果這個 key 在極短時間內(nèi)變化了很多次,那么這個列表里面可能有多個值。

回到最開始需要解決的問題,我們引入 etcd 以后,困難輕輕松松就被解決了:

通過增加方框框住的update_trash_words方法,并把它作為監(jiān)控trash_words這個Key 變化事件的回調(diào)函數(shù),一旦這個 Key 發(fā)生了變化,就會調(diào)用回調(diào)函數(shù),從而更新self.trash_words這個屬性。

運行效果如下圖所示:

可以看到,在紅線上面,我是有臟數(shù)據(jù)的句子是不被過濾的,此時臟字也不是過濾詞。但是當我們在命令行里面更新了 etcd,把新的過濾詞改成垃圾,臟以后,就到了紅線下面,我是有臟數(shù)據(jù)的句子就會被過濾了。

這樣就做到了同時兼顧時效性和速度,避免了無效的網(wǎng)絡(luò)請求。

參考文獻

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

本文轉(zhuǎn)載自微信公眾號「未聞Code」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系未聞Code公眾號。

 

責(zé)任編輯:武曉燕 來源: 未聞Code
相關(guān)推薦

2021-08-13 12:31:26

Redis代碼Java

2021-09-18 10:20:07

Redis數(shù)據(jù)庫緩存

2023-05-16 07:47:18

RabbitMQ消息隊列系統(tǒng)

2018-08-15 09:48:27

數(shù)據(jù)庫Redis應(yīng)用場景

2020-04-07 14:20:10

RabbitMMySQL數(shù)據(jù)庫

2020-11-04 07:34:02

Redis數(shù)據(jù)類型

2022-07-08 10:09:47

SPLSQL數(shù)據(jù)庫

2024-04-11 13:41:47

2024-12-30 08:32:36

2013-12-25 16:03:39

GitGit 命令

2024-09-19 08:08:25

2015-04-07 10:46:48

Redis

2023-11-13 08:31:25

SpringRedis存儲

2024-12-19 08:50:38

Redis存儲系統(tǒng)

2024-11-04 06:20:00

Redis單線程

2021-09-02 18:47:02

redis存儲中間件Remote Dict

2022-10-17 00:27:20

二叉樹數(shù)組索引

2013-10-15 10:11:33

產(chǎn)品測試使用場景產(chǎn)品

2022-10-28 07:15:26

策略模式使用場景UML

2023-10-30 00:11:48

微服務(wù)負載均衡場景
點贊
收藏

51CTO技術(shù)棧公眾號