iT邦幫忙

0

Week21 - 用Redis來幫Line bot髒沙發設計一次性功能 - 概念篇 [Server的終局之戰系列]

本文章同時發佈於:


大家好,今天要介紹的是Redis的應用,主要是最近我自己的Side Project髒沙發要做一個新功能(怎麼有一點工商味道XD),就是

可以在群組裡面辨識照片

使用上就是在群組邀請髒沙發進來後,只要打了「辨識」,就有一次的圖片辨識機會,這樣髒沙發在群組裡面就不會一偵測到圖片就辨識,不然傳個親戚照就辨識就有趣了XD。

這個功能大致是這樣實作的:

  1. 在群組輸入「辨識」
  2. Server紀錄此群組要求辨識圖片
  3. 此群組上傳圖片,辨識之後回傳資料

實作上會碰到以下問題:

  1. 群組在傳送圖片時,必需要檢查此群組是否有打過「辨識」,那代表,此群組每次傳圖Server都要去檢查狀態。如果是實作在PostgresqlorMongoDB這樣持久化的DB,每次查詢都是一次Query,DB會忙死。
  2. 如果儲存在持久化的DB,那如果群組打了「辨識」,最後卻大家都退群了,從來都沒上傳過圖片過,那這份紀錄就一直存在DB裡,變成一個廢棄的資料。

這時候就可以用Redis就可以用來解決:

  1. 在群組發送圖片的檢查從持久化的DB改為資料存在memoryRedis,以減少持久化DB的負擔。
  2. Redis可以設定TTL,即資料的有效時間,只要時間一到,就會將資料刪除。(這邊說明一下雖然MongoDB也有TTL的功能,但既然有1的考量就全部交給Redis來做了XD)

Redis要考量到什麼?

先說結論:

Redis要盡量放「丟掉也沒關係」的資料

Redis偏向CAPCP特性,即是:

資料不論怎麼讀都會一樣的Consistency - 「一致性」,系統出錯而生出新的資料分區的Partition tolerance - 「分區容錯性」

為什麼說「偏向CP」呢?那是因為現在系統其實沒有絕對的CAP,都是「比較想解決什麼問題」的模式。(可參考: Please stop calling databases CP or AP)

先說「分區容錯性」,在Redis有叢集模式(Cluster),即多個在不同電腦上的小Redis一起組成一個大Redis,就是說在一個小Redis掛掉時,或是流量更大時,可以在產生其他小Redis來維持系統。

再來「一致性」,在只有一個Redis的單體模式(Single Instance)的狀況中,讀到的資料是一致的。

但在叢集模式下,其實讀到的資料是可能不一致的,比如說一開始資料存在小Redis A,而後來去讀取大Redis時讀取了小Redis B,那就找不到資料了。

但是,大Redis會盡量複製小Redis的資料給彼此,以盡量保持一致性,這就是為什麼說「偏向CP」的原因。(可參考: Is jedis synchronous or async? What consistency guarantee does redis provide?
)

但是不論在單體還是叢集的模式下,Redis當機而關機了,那資料就全沒了,重開機也找不到,所以他不符合Availability - 「可用性」。

但其實你也可以透過一些額外方案,例如Redis Sentinel來使用故障轉移來達到高可用性XD,所以才會說「偏向」何種特性。(可參考: Redis HA 2 - Redis Sentinel)

統整一下,我們可以把CAP分為以下特性:

  1. Consistency - 一致性: 讀到資料都相同
  2. Availability - 可用性: 資料庫是否高可用,是否會檔案遺失?是否會讀不到資料?
  3. Partition tolerance - 分區容錯性: 當系統出現問題時,可以啟動其他資料分區來維持系統

並且CAP一定只能滿足其中兩項,

因為不可能有可以在不同電腦裡面資料都一致性,並且每台電腦都不會當機的系統

所以,以上討論後,會知道一個單純的Redis,可用性一定是最大的問題,所以才要放「丟掉也沒關係」的資料。

結論

所以,Redis適合用在以下需求的系統:

  1. Low latency - 低延遲,即需要快速讀取資料
  2. 丟掉資料也沒關係

符合髒沙發的群組辨識功能,需要快速檢查群組是否有要求辨識圖片,並且這筆資料丟掉也沒關係,因為就只是群組要再打一次辨識而已XD。

當然如果設計上覺得再打一次辨識是非常嚴重的,那就要追求「偏向CA」的系統,Postgresql就是偏向這種,但就要放棄Redis的好處Low latency

以整個情境來看,無法快速檢查群組是否有要求辨識圖片,是比這筆資料丟掉還嚴重的。


謝謝你的閱讀,也歡迎分享討論指正~

參考資料


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言