Redis的正確使用姿勢

来源:https://www.cnblogs.com/coding-night/archive/2019/04/08/10668660.html
-Advertisement-
Play Games

前言 說到分散式緩存,可能大多數人腦海浮現的就是redis了,為什麼redis能夠在競爭激烈的緩存大戰中脫穎而出呢?原因無非有一下幾點:性能好,豐富的特性跟數據結構,api操作簡單。但是用的人多了,就會出現很多不規範或者疏忽的地方,嚴重的時候甚至會導致生產事故,所以我們有必要來聊聊在Redis使用過 ...


前言

 

說到分散式緩存,可能大多數人腦海浮現的就是redis了,為什麼redis能夠在競爭激烈的緩存大戰中脫穎而出呢?原因無非有一下幾點:性能好,豐富的特性跟數據結構,api操作簡單。但是用的人多了,就會出現很多不規範或者疏忽的地方,嚴重的時候甚至會導致生產事故,所以我們有必要來聊聊在Redis使用過程中的一些“正確姿勢“。

 

 

切忌裸奔

 

大家別笑... 很多初學者或者沒經驗的開發人員在伺服器上用root用戶裝了redis以後,打開預設埠直接就愉快的運行起來了,開放了外網及預設埠的連接,甚至對於生產環境也這樣,貪圖一時的方便,這種情況比較多的出現在一些初創公司 (包括N年前的我也這麼乾過...)

 

那麼會出現什麼問題呢?最常見的就是Redis未授權訪問漏洞。攻擊者掃描到互聯網開放的ip以及預設的6379埠後,直接在本地遠程連接你伺服器的redis,通過redis的命令將本機生成的公鑰寫入到伺服器的authorized.keys中,這時候本機就可以ssh免密登錄進來了。接下來可以寫入反彈shell,提權,然後就可以為所欲為了,這就是為什麼你的伺服器上面會突然出現有挖礦程式的一個原因。

 

為了防止出現上述的風險,我們可以從以下幾個地方來處理。

  • 修改預設埠6379

  • 綁定內網訪問 bing 127.0.0.1

  • 添加redis的密碼驗證

  • 以低許可權的用戶運行redis

  • 必要時設置防火牆策略

 

 

禁止“ key *” ,用“scan”代替

 

說到這個,筆者也是滿滿的淚,在年少無知的時候曾經在生產環境執行過這個命令,後來差點收拾背包提前下班了。為什麼這個操作這麼可怕呢?“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是一個約定俗成的東西,自己使用的時候就儘量不要用一些比較特殊的字元來代替。關於我們的key設計可以參照我們的關係型資料庫。

 

假如有一個user表,有userid,age,username欄位,那麼我們key就可以"user:userid:useridValue:username"這麼來設計,把表名作為key的首碼,查詢的條件放在最後。中間用欄位跟它所對應的value分割開來,所有的設計都是為了在查詢的時候可以更便捷。

 

合理使用多個db

 

redis的db下標預設0-15,也就是有16個。通常大部分人都是使用db0,所有的k-v都在一個庫中。這其實沒多大問題,但是redis不是關係型資料庫,存儲的數據相互耦合不那麼大,所以建議可以按照不同的業務把數據分散到各個庫中,這樣我們可以select 不同的 db 來執行不同的業務模塊操作。

 

善用5種數據結構

 

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的話題,其實還有很多,比如發佈訂閱,持久化機制,集群等。很多最佳實踐都需要結合自身的業務不斷摸索,還是那句話,適合自己的才是最好的。

文章始發於微信公眾號《深夜裡的程式猿》,轉載請註明出處,侵權必究。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HTML部分 js部分 ...
  • 接手項目之後,在安裝依賴後,再npm start的過程中報錯./node_modules/history/esm/history.js Module not found: Can't resolve '@babel/runtime/helpers/esm/extends' ...
  • 最近一個星期準備學習一下angular前端框架,因為之前在學習abp框架的時候,都要求前端要掌握angular,所以不得不回來惡補一下了,學習的過程有時間的話會記錄在這裡,方便以後複習。 閑言少敘,下麵來介紹開發環境搭建的步驟: 開發環境搭建 1.安裝node和npm(其實只需要安裝node,因為n ...
  • 前言: 相信大家都打開過層級很多很多的文件夾。如果把第一個文件夾看作是樹的根節點的話,下麵的子文件夾就可以看作一個子節點。不過最終我們尋找的還是文件夾中的文件,文件可以看做是葉子節點。下麵我們介紹一種模式,與這種樹級結構息息相關。當然,今天的主角是HashMap。接下來我們一起來看HashMap中到 ...
  • 一、引言 我們都知道,資料庫連接是很珍貴的資源,頻繁的開關資料庫連接是非常浪費伺服器的CPU資源以及記憶體的,所以我們一般都是使用資料庫連接池來解決這一問題,即創造一堆等待被使用的連接,等到用的時候就從池裡取一個,不用了再放回去,資料庫連接在整個應用啟動期間,幾乎是不關閉的,除非是超過了最大閑置時間。 ...
  • 歡迎大家的不嫌棄,繼續和我一起學習設計模式。上一篇已經把裝飾者模式的類圖有了一個整體的出來,末尾說的去想想實現的代碼,你實踐了嗎?是什麼原因讓你實踐了呢?又是什麼原因讓你沒有動手呢?沒動手,可能是思路還不夠明確是嗎? 接下來,我們繼續學習。通過代碼實現的方式,來搞定裝飾者模式。 寫下代碼 動手的時候 ...
  • JAVA的主要優勢:跨平臺性,可以在Linux,windows,mac三個系統上運行。 跨平臺的核心:JAVA虛擬機--JVM 原理就是將Java語言在這個系統上翻譯。JAVA在jvm上運行,jvm進行翻譯。 JRE:java的運行環境,包括JVM和所需要的核心類。 JDK:java程式的開發包,包 ...
  • 背景 《SRE Google運維解密》里提到SRE自動化系統的一個bug導致幾乎所有的數據中心機器被成功下線併進行硬碟擦除。當然這本書出版之後又業界也進行了很多的演進。在我們團隊現在很難發生這樣的事情。因為團隊內人人要遵循的一個設計原則是:原則上禁止批量操作。如需批量,需要有審核流程。批量設置上限。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...