本文章同時發佈於:
大家好,今天要介紹的是Redis的應用,主要是最近我自己的Side Project髒沙發要做一個新功能(怎麼有一點工商味道XD),就是
可以在群組裡面辨識照片

使用上就是在群組邀請髒沙發進來後,只要打了「辨識」,就有一次的圖片辨識機會,這樣髒沙發在群組裡面就不會一偵測到圖片就辨識,不然傳個親戚照就辨識就有趣了XD。
這個功能大致是這樣實作的:
實作上會碰到以下問題:
PostgresqlorMongoDB這樣持久化的DB,每次查詢都是一次Query,DB會忙死。這時候就可以用Redis就可以用來解決:
memory的Redis,以減少持久化DB的負擔。Redis可以設定TTL,即資料的有效時間,只要時間一到,就會將資料刪除。(這邊說明一下雖然MongoDB也有TTL的功能,但既然有1的考量就全部交給Redis來做了XD)Redis要考量到什麼?先說結論:
Redis要盡量放「丟掉也沒關係」的資料
Redis偏向CAP中CP特性,即是:
資料不論怎麼讀都會一樣的
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分為以下特性:
Consistency - 一致性: 讀到資料都相同Availability - 可用性: 資料庫是否高可用,是否會檔案遺失?是否會讀不到資料?Partition tolerance - 分區容錯性: 當系統出現問題時,可以啟動其他資料分區來維持系統並且CAP一定只能滿足其中兩項,
因為不可能有可以在不同電腦裡面資料都一致性,並且每台電腦都不會當機的系統
所以,以上討論後,會知道一個單純的Redis,可用性一定是最大的問題,所以才要放「丟掉也沒關係」的資料。
所以,Redis適合用在以下需求的系統:
Low latency - 低延遲,即需要快速讀取資料符合髒沙發的群組辨識功能,需要快速檢查群組是否有要求辨識圖片,並且這筆資料丟掉也沒關係,因為就只是群組要再打一次辨識而已XD。
當然如果設計上覺得再打一次辨識是非常嚴重的,那就要追求「偏向CA」的系統,Postgresql就是偏向這種,但就要放棄Redis的好處Low latency。
以整個情境來看,無法快速檢查群組是否有要求辨識圖片,是比這筆資料丟掉還嚴重的。
謝謝你的閱讀,也歡迎分享討論指正~