Redis從入門到精通:初級篇

来源:https://www.cnblogs.com/xrq730/archive/2018/04/25/8890896.html
-Advertisement-
Play Games

原文鏈接:http://www.cnblogs.com/xrq730/p/8890896.html,轉載請註明出處,謝謝 Redis從入門到精通:初級篇 平時陸陸續續看了不少Redis的文章了,工作中也一直在用Redis,感覺是時候對過往Redis的所學進行一次系統性的總結。《Redis從入門到精通 ...


原文鏈接:http://www.cnblogs.com/xrq730/p/8890896.html,轉載請註明出處,謝謝

 

Redis從入門到精通:初級篇

平時陸陸續續看了不少Redis的文章了,工作中也一直在用Redis,感覺是時候對過往Redis的所學進行一次系統性的總結。《Redis從入門到精通》系列會分為初級、中級、高級三篇,從淺入深講解Redis相關知識點。

在本文中,我們將看到以下內容:

  • Redis簡介
  • Redis安裝、啟動
  • Redis登錄授權
  • Redis配置文件redis.conf中參數詳細的一個解讀
  • Redis性能測試

這些內容無關具體用法,作為一些初級的知識,系統地先認識一下Redis。

 

Redis簡介

Redis是一款開源的使用ANSI C語言編寫、遵守BSD協議、支持網路、可基於記憶體也可持久化的日誌型、Key-Value高性能資料庫。Redis與其他Key-Value緩存產品相比有以下三個特點:

  • 支持數據持久化,可以將記憶體中的數據保存在磁碟中,重啟可再次載入使用
  • 支持簡單的Key-Value類型的數據,同時還提供List、Set、Zset、Hash等數據結構的存儲
  • 支持數據的備份,即Master-Slave模式的數據備份

同時,我們再看下Redis有什麼優勢:

  • 讀速度為110000次/s,寫速度為81000次/s,性能極高
  • 具有豐富的數據類型,這個上面已經提過了
  • Redis所有操作都是原子的,意思是要麼成功執行要麼失敗完全不執行,多個操作也支持事務
  • 豐富的特性,比如Redis支持publish/subscribe、notify、key過期等

 

Redis安裝、啟動

這次寫Redis系列的文章,LZ特意去阿裡雲上買了一個月的伺服器,操作系統是Linux,因為Redis項目本身不正式支持Windows系統。不過微軟開放技術小組開發和維護了Windows版本的Redis,下載地址為https://github.com/MicrosoftArchive/redis/releases,感興趣的可以自己去試下,LZ在自己筆記本上安裝啟動過,沒有問題,但就不細說了。

下麵說一下在Linux系統上安裝並啟動Redis的步驟(我的Redis安裝在/data/component/redis目錄下,每一步使用的命令標紅加粗):

  • 進入目錄,cd /data/component/redis
  • 下載Redis,wget http://download.redis.io/releases/redis-3.2.11.tar.gz,可以看到LZ使用的Redis版本是3.2.11,在LZ寫這篇文章的時候,Redis最新版本為4.0.9,地址為http://download.redis.io/releases/redis-4.0.9.tar.gz,感興趣的朋友也可以用這個版本
  • 解壓下載下來的tar包,tar -zxvf redis-3.2.11.tar.gz,解壓完畢的文件夾名稱為redis-3.2.11
  • 進入redis-3.2.11,cd redis-3.2.11
  • 由於我們下載下來的是源文件,因此使用make命令對源文件進行一個構建,構建完畢我們會發現src目錄下多出了redis-benchmark、redis-check-aof、redis-check-rdb、redis-cli、redis-sentinel、redis-server幾個可執行文件,這幾個可執行文件後面會說到
  • 由於上述幾個命令在/data/component/redis/redis-3.2.11/src目錄下,為了更方便地使用這幾個命令而不需要指定全路徑,配置一下環境變數。這裡我是以非root用戶進行登錄的,因此配置用戶變數,先執行cd命令回到初始目錄,再vi ./.bash_profile,在path這一行加入PATH=$PATH:$HOME/.local/bin:$HOME/bin:/data/component/redis/redis-3.2.11/src,使用:wq保存並退出
  • 使環境變數生效,執行source ./.bash_profile
  • 使用redis-server即可啟動redis,redis-server /data/component/redis/redis-3.2.11/redis.conf

不過這個時候我們的啟動稍微有點問題,不是後臺啟動的,即ctrl+c之後Redis就停了:

為瞭解決這個問題,我們需要修改一下redis.conf,將Redis設置為以守護進程的方式進行啟動,打開redis.conf,找到daemonize,將其設置為yes即可:

這個時候先關閉一下再啟動,Redis就在後臺自動運行了,關閉Redis有兩種方式:

  • redis-cli shutdown,這是種安全關閉redis的方式,但這種寫法只適用於沒有配置密碼的場景,比較不安全,配置密碼下一部分會講
  • kill -9 pid,這種方式就是強制關閉,可能會造成數據未保存

重啟後,我們可以使用ps -ef | grep redisnetstat -ant | grep 6379命令來驗證Redis已經啟動。

 

Redis登錄授權

上面我們安裝了Redis,但這種方式是非常不安全的,因為沒有密碼,這樣任何連接上Redis伺服器的用戶都可以對Redis執行操作,所以這一部分我們來講一下給Redis設置密碼。

打開redis.conf,找到"requirepass"部分,打開原本關閉的註釋,替換一下自己想要的密碼即可:

重啟Redis,授權登錄有兩種做法:

  • 連接的時候直接指定密碼,redis-cli -h 127.0.0.1 -p 6379 -a 123456
  • 連接後授權,redis-cli -h 127.0.0.1 -p 6379auth 123456

在配置了密碼的情況下,沒有進行授權,那麼對Redis發送的命令,將返回"(error) NOAUTH Authentication required."。

 

Redis配置文件redis.conf

上面兩小節,設置使用守護線程啟動、設置密碼,都需要修改redis.conf,說明redis.conf是Redis核心的配置文件,本小節我們來看一下redis.conf中一些常用配置:

配置 作用 預設
bind

當配置了bind之後:

  • 只有bind指定的ip可以直接訪問Redis,這樣可以避免將Redis服務暴露於危險的網路環境中,防止一些不安全的人隨隨便便通過遠程訪問Redis
  • 如果bind選項為空或0.0.0.0的話,那會接受所有來自於可用網路介面的連接
127.0.0.1
protected-mode

protected-mode是Redis3.2之後的新特性,用於加強Redis的安全管理,當滿足以下兩種情況時,protected-mode起作用:

  • bind未設置,即接收所有來自網路的連接
  • 密碼未設置

當滿足以上兩種情況且protected-mode=yes的時候,訪問Redis將報錯,即密碼未設置的情況下,無密碼訪問Redis只能通過安裝Redis的本機進行訪問

yes
port Redis訪問埠,由於Redis是單線程模型,因此單機開多個Redis進程的時候會修改埠,不然一般使用大家比較熟悉的6379埠就可以了 6379
tcp-backlog 半連接隊列的大小,對半連接隊列不熟的可以看我以前的文章TCP:三次握手、四次握手、backlog及其他 511
timeout 指定在一個client空閑多少秒之後就關閉它,0表示不管 0
tcp-keepalive

設置tcp協議的keepalive,從Redis的註釋來看,這個參數有兩個作用:

  • 發現死的連接
  • 從中間網路設備的角度看連接是否存活
300
daemonize 這個前面說過了,指定Redis是否以守護進程的方式啟動 no
supervised 這個參數表示可以通過upstart和systemd管理Redis守護進程,這個具體和操作系統相關,資料也不是很多,就暫時不管了 no
pidfile 當Redis以守護進程的方式運行的時候,Redis預設會把pid寫到pidfile指定的文件中 /var/run/redis_6379.pid
loglevel

指定Redis的日誌級別,Redis本身的日誌級別有notice、verbose、notice、warning四種,按照文檔的說法,這四種日誌級別的區別是:

  • debug,非常多信息,適合開發/測試
  • verbose,很多很少有用的信息(直譯,讀著拗口,從上下文理解應該是有用信息不多的意思),但並不像debug級別這麼混亂
  • notice,適度的verbose級別的輸出,很可能是生產環境中想要的
  • warning,只記錄非常重要/致命的信息
notice
logfile 配置log文件地址,預設列印在命令行終端的視窗上 ""
databases 設置Redis資料庫的數量,預設使用0號DB 16
 save 把Redis數據保存到磁碟上,這個是在RDB的時候用的,介紹RDB的時候專門說這個 

save 900 1

save 300 10

save 60 10000 

 stop-writes-on-bgsave-error

當啟用了RDB且最後一次後臺保存數據失敗,Redis是否停止接收數據。

這會讓用戶意識到數據沒有正確持久化到磁碟上,否則沒有人會註意到災難(disaster)發生了。

如果Redis重啟了,那麼又可以重新開始接收數據了

 yes
rdbcompression  是否在RBD的時候使用LZF壓縮字元串,如果希望省點CPU,那就設為no,不過no的話數據集可能就比較大  yes 
 rdbchecksum 是否校驗RDB文件,在RDB文件中有一個checksum專門用於校驗 yes 
 dbfilename dump的文件位置 dump.rdb 
 dir Redis工作目錄 ./ 
 slaveof 主從複製,使用slaveof讓一個節點稱為某個節點的副本,這個只需要在副本上配置  關閉
masterauth 如果主機使用了requirepass配置進行密碼保護,使用這個配置告訴副本連接的時候需要鑒權 關閉
slave-serve-stale-data

當一個Slave與Master失去聯繫或者複製正在進行中,Slave可能會有兩種表現:

  • 如果為yes,Slave仍然會應答客戶端請求,但返回的數據可能是過時的或者數據可能是空的
  • 如果為no,在執行除了INFO、SLAVEOF兩個命令之外,都會應答"SYNC with master in progres"錯誤
yes
 slave-read-only 配置Redis的Slave實例是否接受寫操作,即Slave是否為只讀Redis  yes
 slave-priority 從站優先順序是可以從redis的INFO命令輸出中查到的一個整數。當主站不能正常工作時,redis sentinel使用它來選擇一個從站並將它提升為主站。 
低優先順序的從站被認為更適合於提升,因此如果有三個從站優先順序分別是10, 100, 25,sentinel會選擇優先順序為10的從站,因為它的優先順序最低。 
然而優先順序值為0的從站不能執行主站的角色,因此優先順序為0的從站永遠不會被redis sentinel提升。 
100 
 requirepass 設置客戶端認證密碼 關閉 
 rename-command

命令重命名,對於一些危險命令例如:

  • flushdb(清空資料庫)
  • flushall(清空所有記錄)
  • config(客戶端連接後可配置伺服器)
  • keys(客戶端連接後可查看所有存在的鍵)                   

作為服務端redis-server,常常需要禁用以上命令來使得伺服器更加安全,禁用的具體做法是是:

  • rename-command FLUSHALL ""

也可以保留命令但是不能輕易使用,重命名這個命令即可:

  • rename-command FLUSHALL abcdefg

這樣,重啟伺服器後則需要使用新命令來執行操作,否則伺服器會報錯unknown command

關閉 
maxclients  設置同時連接的最大客戶端數量,一旦達到了限制,Redis會關閉所有的新連接併發送一個"max number of clients reached"的錯誤 關閉,預設10000 
 maxmemory 不要使用超過指定數量的記憶體,一旦達到了,Redis會嘗試使用驅逐策略來移除鍵  關閉 
 maxmemory-policy

當達到了maxmemory之後Redis如何移除數據,有以下的一些策略:

  • volatile-lru,使用LRU演算法,移除範圍為設置了失效時間的
  • allkeys-lru,根據LRU演算法,移除範圍為所有的
  • volatile-random,使用隨機演算法,移除範圍為設置了失效時間的
  • allkeys-random,使用隨機演算法,移除範圍為所有的
  • volatile-ttl,移除最近過期的數據
  • noeviction,不過期,當寫操作的時候返回錯誤

註意,當寫操作且Redis發現沒有合適的數據可以移除的時候,將會報錯

關閉,noeviction
appendonly  是否開啟AOF,關於AOF後面再說   no
appendfilename AOF文件名稱 appendonly.aof
appendfsync 

操作系統實際寫數據到磁碟的頻率,有以下幾個選項:

  • always,每次有寫操作都進行同步,慢,但是最安全
  • everysec,對寫操作進行累積,每秒同步一次,是一種折衷方案
  • no,當操作系統flush緩存的時候同步,性能更好但是會有數據丟失的風險

當不確定是使用哪種的時候,官方推薦使用everysec,它是速度與數據安全之間的一種折衷方案

everysec 
 no-appendfsync-on-rewrite

aof持久化機制有一個致命的問題,隨著時間推移,aof文件會膨脹,當server重啟時嚴重影響資料庫還原時間,因此系統需要定期重寫aof文件。

重寫aof的機製為bgrewriteaof(另外一種被廢棄了,就不說了),即在一個子進程中重寫從而不阻塞主進程對其他命令的處理,但是這依然有個問題。

bgrewriteaof和主進程寫aof,都會操作磁碟,而bgrewriteaof往往涉及大量磁碟操作,這樣就會讓主進程寫aof文件阻塞。

針對上述問題,可以使用此時可以使用no-appendfsync-on-rewrite參數做一個選擇:

  • no,最安全,不丟失數據,但是需要忍受阻塞
  • yes,數據寫入緩衝區,不造成阻塞,但是如果此時redis掛掉就會丟失數據,在Linux操作系統預設設置下,最壞場景下會丟失30秒數據
 no
 auto-aof-rewrite-percentage 本次aof文件超過上次aof文件該值的百分比時,才會觸發rewrite  100 
 auto-aof-rewrite-min-size aof文件最小值,只有到達這個值才會觸發rewrite,即rewrite由auto-aof-rewrite-percentage+auto-aof-rewrite-min-size共同保證  64mb
 aof-load-truncated

redis在以aof方式恢複數據時,對最後一條可能出問題的指令的處理方式: 

  • yes,log並繼續
  • no,直接恢復失敗
 yes
 slowlog-log-slower-than Redis慢查詢的最低條件,單位微妙,即查詢時間>這個值的會被記錄   10000
 slowlog-max-len Redis存儲的慢查詢最大條數,超過該值之後會將最早的slowlog剔除 128 
lua-time-limit 一個lua腳本執行的最大時間,單位為ms 5000
cluster-enabled 正常來說Redis實例是無法稱為集群的一部分的,只有以集群方式啟動的節點才可以。為了讓Redis以集群方式啟動,就需要此參數。 關閉
cluster-config-file 每個集群節點應該有自己的配置文件,這個文件是不應該手動修改的,它只能被Redis節點創建且更新,每個Redis集群節點需要不同的集群配置文件 關閉,nodes-6379.conf 
 cluster-node-timeout 集群中一個節點向其他節點發送ping命令時,必須收到回執的毫秒數  關閉,15000
cluster-slave-validity-factor

如果該項設置為0,不管Slave節點和Master節點間失聯多久都會一直嘗試failover。

比如timeout為5,該值為10,那麼Master與Slave之間失聯50秒,Slave不會去failover它的Master

關閉,10 
cluster-migration-barrier

當一個Master擁有多少個好的Slave時就要割讓一個Slave出來。

例如設置為2,表示當一個Master擁有2個可用的Slave時,它的一個Slave會嘗試遷移

關閉,1
cluster-require-full-coverage 

有節點宕機導致16384個Slot全部被覆蓋,整個集群是否停止服務,這個值一定要改為no

關閉,yes

以上把redis.conf裡面幾乎所有的配置都寫了一遍(除了ADVANCED CONFIG部分),感覺其他博客很少有看到比我這個還全的了^_^,給大家作為參考吧。

 

Redis性能測試

之前說過Redis在make之後有一個redis-benchmark,這個就是Redis提供用於做性能測試的,它可以用來模擬N個客戶端同時發出M個請求。首先看一下redis-benchmark自帶的一些參數:

參數 作用 預設值
-h 伺服器名稱 127.0.0.1
-p 伺服器埠 6379
-s 伺服器Socket
-c 並行連接數 50
-n 請求書 10000
-d SET/GET值的位元組大小 2
-k 1表示keep alive,0表示重連 1
-r

SET/GET/INC使用隨機Key而不是常量,在形式上key樣子為mykey_ran:000000012456

-r的值決定了value的最大值

-p 使用管道請求 1,即不使用管道
-q 安靜模式,只顯示query/sec值
--csv 使用csv格式輸出
-l 迴圈,無限運行測試
-t 只運行使用逗號分割的命令的測試
-I 空閑模式,只打開N個空閑線程並且等待

拋開配置只談性能的都是耍流氓,說一下我買的阿裡雲伺服器的配置:

  • 單核CPU,CPU類型為Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz
  • 記憶體4G
  • 帶寬1M
  • 操作系統為Centos7

首先我們運行最簡單的redis-benchmark -q,運行結果為:

列印了每個命令的QPS,看到基本都在讀寫速度基本都在100000次/s以上。

接著換一個命令進行測試,因為實際場景中我們的Key和Value一定是非常豐富的,不可能是單一的Key和單一的Value,因此接著去的測試使用-r模擬value到100000且將運行次數提高到1000000次,具體命令為redis-benchmark -q -r 100000 -n 1000000,運行結果為:

看到整個讀寫效率基本都在110000次/s以上,證明瞭讀寫的高效率。

簡單對於Redis的性能測試就到這兒,這個測試結果看起來很美,但是實際應用卻完全不是,主要體現在以下幾點:

  • 網路與帶寬,這是現實中最主要的影響因素,上面的測試還是太過於低級,現實使用中Redis裡面存一個用戶信息、訂單信息,幾KB的大小,100000qps根本不可能大家可以算算需要多大的帶寬,粗粗算一下超過1個G吧,很多線上服務的帶寬根本達不到1G/s,所以Redis的吞吐量最先會被網路帶寬限制住
  • Redis由於是單線程模型,因此CPU性能非常重要,尤其是大緩存的快速CPU,我這裡的CPU上面寫過了,Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz總體還是可以的
  • 客戶端連接數,上面使用了預設的連接數50,實際上10W、20W甚至100W+呢?不過得益於epoll模型,整個下降的可以接受,下麵有一張連接數和qps的關係,我也是網上找來的
  • RDB和AOF可能會對Redis造成的阻塞並未考慮進去
  • 儘可能使用大記憶體,避免SWAP

無論如何,總而言之,Redis整個性能是非常不錯的,個人認為如果要選一款存儲系統,那麼Redis應當是首選。


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

-Advertisement-
Play Games
更多相關文章
  • 一、為什麼要有操作系統 二、什麼是操作系統 精簡的說的話,操作系統就是一個協調、管理和控制電腦硬體資源和軟體資源的控製程序。操作系統所處的位置如圖1 細說的話,操作系統應該分成兩部分功能: #作用一:為應用程式提供如何使用硬體資源的抽象 例如:操作系統提供了文件這個抽象概念,對文件的操作就是對磁碟 ...
  • 1 //SINEWAVE.C -- Sine Wave Using Polyline (c) Charles Petzold, 1998 2 #include <Windows.h> 3 #include <math.h> 4 5 #define NUM 1000 6 #define TWOPI ( ...
  • GitHub是一個免費托管開源代碼的遠程倉庫。但是對於某些視源代碼如生命的商業公司來說,既不想公開源代碼,又捨不得給GitHub交保護費,那就只能自己搭建一臺Git伺服器作為私有倉庫使用。搭建Git伺服器需要準備一臺運行Linux的機器,強烈推薦用Ubuntu或Debian,這樣,通過幾條簡單的ap ...
  • 獲取設備環境的信息 1 //DEVCAPS1.C--Device Capabilities Display Program No.1 (c) Charles Petzold, 1998 2 #include <Windows.h> 3 4 #define NUMLINES ((int) (sizeo ...
  • This network connection does not exist 在windows server 2008上面map了一個磁碟,共用的folder被我停止共用後,點擊該磁碟的disconnect,跳出提示信息: This network connection does not exist ...
  • 在MySQL資料庫中出現了阻塞問題,如何快速查找定位問題根源?在實驗開始前,我們先梳理一下有什麼工具或命令查看MySQL的阻塞,另外,我們也要一一對比其優劣,因為有些命令可能在實際環境下可能並不適用。 1: show engine innodb status 2: Innotop工具 3: INNO... ...
  • Linux作為操作系統,Apache 或Nginx作為 Web 伺服器,MySQL 作為資料庫,PHP/Perl/Python作為伺服器端腳本解釋器。這四個軟體都是免費或開源軟體軟體,因此使用這種方式除開人工成本就可以建立起一個穩定、免費的網站系統,稱為“LAMP“或“LNMP”組合。 一、以cmd ...
  • 大數據時代不可抗拒,應該是毋庸置疑的,但對於絕大多數企業來說,大數據本身僅是一個空泛的概念,不僅難以參與更難於控制。幾乎任何規模企業,每時每刻都在產生大量的數據,但這些數據如何歸集、提煉始終是一個困擾,這種感覺好像是守著金山卻無從下手。大數據技術的意義不在於掌握龐大的數據信息,而在於對這些數據進行智 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...