本文章同時發佈於:
大家好,今天要介紹的是Redis
的應用,主要是最近我自己的Side Project
髒沙發要做一個新功能(怎麼有一點工商味道XD),就是
可以在群組裡面辨識照片
使用上就是在群組邀請髒沙發進來後,只要打了「辨識」,就有一次的圖片辨識機會,這樣髒沙發在群組裡面就不會一偵測到圖片就辨識,不然傳個親戚照就辨識就有趣了XD。
這個功能大致是這樣實作的:
實作上會碰到以下問題:
Postgresql
orMongoDB
這樣持久化的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
。
以整個情境來看,無法快速檢查群組是否有要求辨識圖片,是比這筆資料丟掉還嚴重的。
謝謝你的閱讀,也歡迎分享討論指正~