前言面試
說到分佈式緩存,可能大多數人腦海浮現的就是redis了,爲何redis可以在競爭激烈的緩存大戰中脫穎而出呢?緣由無非有一下幾點:性能好,豐富的特性跟數據結構,api操做簡單。可是用的人多了,就會出現不少不規範或者疏忽的地方,嚴重的時候甚至會致使生產事故,因此咱們有必要來聊聊在Redis使用過程當中的一些「正確姿式「。redis
切忌裸奔shell
你們別笑... 不少初學者或者沒經驗的開發人員在服務器上用root用戶裝了redis之後,打開默認端口直接就愉快的運行起來了,開放了外網及默認端口的鏈接,甚至對於生產環境也這樣,貪圖一時的方便,這種狀況比較多的出如今一些初創公司 (包括N年前的我也這麼幹過...)數據庫
那麼會出現什麼問題呢?最多見的就是Redis未受權訪問漏洞。攻擊者掃描到互聯網開放的ip以及默認的6379端口後,直接在本地遠程鏈接你服務器的redis,經過redis的命令將本機生成的公鑰寫入到服務器的authorized.keys中,這時候本機就能夠ssh免密登陸進來了。接下來能夠寫入反彈shell,提權,而後就能夠隨心所欲了,這就是爲何你的服務器上面會忽然出現有挖礦程序的一個緣由。api
爲了防止出現上述的風險,咱們能夠從如下幾個地方來處理。緩存
說到這個,筆者也是滿滿的淚,在年少無知的時候曾經在生產環境執行過這個命令,後來差點收拾揹包提早下班了。爲何這個操做這麼可怕呢?「key *」 操做的意思是返回數據庫中全部匹配的key,它會掃一次性掃描全部的記錄,當你庫裏的數據量很大的時候,會形成redis的阻塞,cpu使用率飆升,慢慢的拖垮項目中對redis的相關請求直至出現各類timeout...安全
在Redis2.8版本之後,提供了一個更好的遍歷key的操做"scan",它相似於咱們jdbc中ResultSet,經過一個遊標來迭代。使用方法爲「SCAN cursor [MATCH pattern] [COUNT count]」。服務器
redis 127.0.0.1:6379> scan 0 1) "17" 2) 1) "key:12" 2) "key:8" 3) "key:4" 4) "key:14" 5) "key:16" 6) "key:17" 7) "key:15" 8) "key:10" 9) "key:3" 10) "key:7" 11) "key:1" redis 127.0.0.1:6379> scan 17 1) "0" 2) 1) "key:5" 2) "key:18" 3) "key:0" 4) "key:2" 5) "key:19" 6) "key:13" 7) "key:6" 8) "key:9" 9) "key:11"
「scan 0 」表示開始一個新的迭代,當返回的第一參數爲0時,則表示迭代結束,若不爲0,下一次迭代的時候帶上這個遊標開始下一次遍歷,直到返回0.第二個參數則是當前遍歷出來的值。使用的時候須要注意版本,當版本低於2.8時,需升級才能使用。數據結構
首先用「:」來分割key是一個約定俗成的東西,本身使用的時候就儘可能不要用一些比較特殊的字符來代替。關於咱們的key設計能夠參照咱們的關係型數據庫。ssh
假若有一個user表,有userid,age,username字段,那麼咱們key就能夠"user:userid:useridValue:username"這麼來設計,把表名做爲key的前綴,查詢的條件放在最後。中間用字段跟它所對應的value分割開來,全部的設計都是爲了在查詢的時候能夠更便捷。
redis的db下標默認0-15,也就是有16個。一般大部分人都是使用db0,全部的k-v都在一個庫中。這其實沒多大問題,可是redis不是關係型數據庫,存儲的數據相互耦合不那麼大,因此建議能夠按照不一樣的業務把數據分散到各個庫中,這樣咱們能夠select 不一樣的 db 來執行不一樣的業務模塊操做。
redis提供了5種數據結構,可是根據以往的面試結果來看,不少應聘者幾乎在項目中只用到string類型,甚至對其餘類型只知其一;不知其二。其實當咱們能在不一樣的場景善用不一樣的結構的話,效率會有很大的提高。下面簡單介紹幾個例子。
SortSet
它提供了一個優先級(score)來排序,咱們能夠把score的值設置成時間戳,這樣咱們能夠經過一些定時的操做來取出某段時間裏面數據,在咱們項目的機器人模塊中有大量的此類操做。還有經常使用的地方是排行榜,經過score值的變化來快速高效的更新榜單。
list
它的實現是一個雙向鏈表,咱們能夠把一些須要執行的任務經過lpush,rpush存放進來,組成符合咱們需求的順序,最後咱們在依次取出來執行,相似於mq。
set
用來作一些自動去重的操做,好比redis的交集命令,能夠取出2我的的共同好友。
redis中有不少高危命令。如「flushdb」,「config」等,咱們能夠禁止或者重命名這些命令來使得操做更加安全。
咱們須要修改redis的配置文件redis.conf,在SECURITY這一項中,新增
rename-command FLUSHALL "" rename-command CONFIG ""
假如是重命名的話
rename-command FLUSHALL abcdefg
配置完重啓後生效。
結語
對於redis的話題,其實還有不少,好比發佈訂閱,持久化機制,集羣等。不少最佳實踐都須要結合自身的業務不斷摸索,仍是那句話,適合本身的纔是最好的。
喜歡的話,關注一下公衆號《深夜裏的程序猿》,天天更新高質量IT文章