redis主從架構(上)

  • 2019 年 11 月 12 日
  • 筆記

1、redis概述

redis的出現時間並不長,是NoSQL中的一種,基於鍵-值型的存儲,與memcache類似,但是memcache中只是內存的緩存,而redis不僅是內存中的緩存,還提供持久存儲,在2009年第一次發佈redis。

Redis 全稱(REmote DIctionary Server)遠程字典服務器,而這個字典服務器從本質上來講,主要是提供數據結構的遠程存儲功能的,可以理解為redis是一個高級的K-V存儲,和數據結構存儲,因為redis除了能夠存儲K-V這種簡單的數據之外,還能夠存儲,列表、字典、hash表、等對應的數據結構。

2、Redis與Memcache對比

1.是一個分佈式的內存對象緩存系統,而redis是可以實現持久存儲。

2.Memcache是一個LRU的緩存,redis支持更多的數據類型。

3.Memcache是多線程的,redis是單線程的。

4.二者性能幾乎不相上下,實際上redis會受到硬盤持久化的影響,但是性能仍然保持在與Memcache不相上下,是非常了不起的。

3、redis與memcache的不同之處

在性能上redis不比memcache差,因為redis整個運行通通都是在內存中實現的,它的所有的數據集都是保存在內存中的,內存中的數據會周期性的寫入到磁盤上,以實現數據的持久功能,而這種寫磁盤並不是用於訪問,而僅是冗餘功能,所以redis所有功能都在內存中完成,因為此性能也是可想而知。

redis與mamcache不同之處在於redis有一個周期性的將數據保存到磁盤上的機制,而且不只一種,有兩種機制,這也是redis持久化的一種實現,另外與mamcache有所區別的是,redis是單線程服務器,只有一個線程來響應所有的請求。

4、redis主從模式

redis支持主從模式,但是redis的主從模式默認就有一個sentinel工具,從而實現主從架構的高可用,也就是說,redis能夠藉助於sentinel工具來監控主從節點,當主節點發生故障時,會自己提升另外一個從節點成為新的主節點。

在redis 3.0版本發佈,開始支持redis集群,從而可以實現分佈式,可以將用戶的請求分散至多個不同節點。

5、redis所支持的數據類型

支持存儲的數據類型有:String(字符串,包含整數), List(列表), Hash(關聯數組), Sets(集合), Sorted Sets(有序集合), Bitmaps(位圖), HyperLoglog

6、redis性能評估

1.100萬較小的鍵存儲字符串,大概消耗100M內存。

2.由於redis是單線程,如果服務器主機上有多個CPU,只有一個能夠使用,但並不意味着CPU會成為瓶頸,因為redis是一個比較簡單的K-V數據存儲,CPU通常不會成為瓶頸的。

3.在常見的linux服務器上,500K(50萬)的並發,只需要一秒鐘處理,如果主機硬件較好的情況下,每秒鐘可以達到上百萬的並發。

7.1Redis的優勢

1.豐富的(資料形態)操作:String(字符串,包含整數), List(列表), Hash(關聯數組), Sets(集合), Sorted Sets(有序集合), Bitmaps(位圖), HyperLoglog。

2.內建Replication和culster(自身支持複製及集群功能)。

3.支持就地更新(in-place update)操作,直接可以在內存中完成更新操作。

4.支持持久化(磁盤)避免雪崩效應,萬一出現雪崩效應,所有的數據都無法恢復,但redis由於有持久性的數據,可以實現恢復。

7.2Memcached的優勢

1.多線程

2.善用多核CPU

3.更少的阻塞操作

4.更少的內存開銷

5.更少的內存分配壓力

6.可能有更少的內存碎片

8、redis主從搭建

主redis:172.17.0.53

從redis:172.17.0.54

8.1編譯安裝

 [root@docker-02 ~]# wget http://download.redis.io/releases/redis-4.0.10.tar.gz   [root@docker-02 ~]# tar xzf redis-4.0.10.tar.gz   [root@docker-02 ~]# cd redis-4.0.10/src   [root@docker-02 src]# make PREFIX=/usr/local/redis install

8.2創建目錄

 [root@docker-02 src]# mkdir -p /usr/local/redis/conf   [root@docker-02 src]# mkdir -p /usr/local/redis/data   [root@docker-02 src]# mkdir -p /usr/local/redis/logs

redis/

├── bin redis二進制文件路徑

├── conf 存放配置

├── data 存放數據

└── logs 存放日誌/pid文件

8.3創建redis用戶

 [root@docker-02 src]# useradd -s /sbin/nologin redis   [root@docker-02 src]# chown -R redis.redis /usr/local/redis/

8.4配置standalone單機模式

 ##配置文件沒有,自己創建配置文件   [root@docker-02 src]# vim /usr/local/redis/conf/redis_6301.conf   ##6301##   ################################## NETWORK #####################################   bind 0.0.0.0   protected-mode yes ##daemonize no Linux Shell終端運行redis,改為yes即後台運行Redis服務   port 6301   tcp-backlog 511 ## 在高並發的環境中,為避免慢客戶端的連接問題,需要設置一個高速後台日誌   timeout 0 ## bind 0.0.0.0#設置客戶端連接時的超時時間,單位為秒。當客戶端在這段時間內沒有發出任何指令,那麼關閉該連接   tcp-keepalive 300 ## 在Linux 上,指定值(秒)用於發送 ACKs 的時間。注意關閉連接需要雙倍的時間。默認為 0   ################################# GENERAL #####################################   daemonize yes ##redis採用的是單進程多線程的模式。當redis.conf中選項daemonize設置成yes時,代表開啟守護進程模式。在該模式下,redis會在後台運行,並將進程pid號寫入至redis.conf選項pidfile設置的文件中,此時redis將一直運行,除非手動kill該進程。   supervised no  ##可以通過upstart和systemd管理Redis守護進程   pidfile /usr/local/redis/logs/6301.pid  ## 當運行多個 redis 服務時,需要指定不同的pid文件和端口   loglevel notice  ##設置服務端的日誌級別   logfile /usr/local/redis/logs/6301.log   databases 16 ##數據庫的總數,默認16個   always-show-logo yes ##是否總是顯示logo   ################################ SNAPSHOTTING ################################   save 9001   save 30010   save 6010000   stop-writes-on-bgsave-error yes ## 默認情況下,如果 redis 最後一次的後台保存失敗,redis 將停止接受寫操作   rdbcompression yes ## 是否在 dump .rdb 數據庫的時候使用 LZF 壓縮字符串   rdbchecksum yes ## 是否校驗rdb文件   dbfilename dump6301.rdb  ## 設置 dump 的文件位置   dir /usr/local/redis/data/  ## 工作目錄   ################################# REPLICATION #################################   # slaveof <masterip> <masterport>   # masterauth <master-password>   slave-serve-stale-data yes ## 當一個 slave 與 master 失去聯繫,或者複製正在進行的時候,slave 可能會有兩種表現   如果為 yes,slave 仍然會應答客戶端請求,但返回的數據可能是過時,   如果為 no ,在你執行除了 info he salveof 之外的其他命令時,slave 都將返回一個 "SYNC with master in progress"的錯誤   slave-read-only yes ## slave 實體是否接受寫入操作,從 redis 2.6 版起,默認 slaves 都是只讀的   repl-diskless-sync no  ##硬盤備份   repl-diskless-sync-delay 5   repl-disable-tcp-nodelay no   slave-priority 100 ##如果 master 不能再正常工作,那麼會在多個 slave 中,選擇優先值最小的一個 slave 提升為 master   優先值為 0表示不能提升為 master   ################################## SECURITY ###################################   requirepass rds6301_paswd  ## 設置認證密碼   ################################### CLIENTS ####################################   maxclients 10000 ## 最大限制   ############################## MEMORY MANAGEMENT ################################   maxmemory 8gb  ## 最大使用內存   maxmemory-policy volatile-lru  ##內存不足"時,數據清除策略,默認為"volatile-lru"   ############################# LAZY FREEING ####################################   lazyfree-lazy-eviction no  ##內存滿逐出選項   lazyfree-lazy-expire no   lazyfree-lazy-server-del no   slave-lazy-flush no  ##全量同步時,slave異步清空所有DB   ############################## APPEND ONLY MODE ###############################   appendonly yes ##以追加的方式記錄所有寫操作   appendfilename "appendonly6301.aof" ##配置設置   appendfsync everysec  ##異步操作,每秒記錄 如果有一秒內宕機,有數據丟失   no-appendfsync-on-rewrite no   auto-aof-rewrite-percentage 100 ##當aof log增長超過指定比例時,重寫log file, 設置為0表示不自動重寫Aof 日誌,重寫是為了使aof體積保持最小,而確保保存最完整的數據。   auto-aof-rewrite-min-size 64mb  ##觸發aof rewrite的最小文件尺寸   aof-load-truncated yes   aof-use-rdb-preamble no  ##配置項可以打開混合開關   ################################ LUA SCRIPTING ###############################   lua-time-limit 5000 ##最大執行時間的長短   ################################ REDIS CLUSTER ###############################   ########################## CLUSTER DOCKER/NAT support ########################   ################################## SLOW LOG ###################################   slowlog-log-slower-than 10000 ## 可以通過兩個參數設置 slow log :一個是告訴 Redis 執行超過多少時間被記錄的參數 slowlog-log-slower-than( 微秒 ) 另一個是 slow log 的長度。當一個新命令被記錄的時候最早的命令將被從隊列中移除   上面的時間以微秒為單位,因此 1000000代表一秒。注意指定一個負數將關閉慢日誌,而設置為 0將強制每個命令都會記錄   slowlog-max-len 128 ##對日誌長度沒有限制,只是要注意它會消耗內存   可以通過 SLOWLOG RESET 回收被慢日誌消耗的內存   推薦使用默認值 128,當慢日誌超過 128時,最先進入隊列的記錄會被踢出   ################################ LATENCY MONITOR ##############################   latency-monitor-threshold 0 ##默認情況下延時監控   ############################# EVENT NOTIFICATION ##############################   notify-keyspace-events "" ##開啟或關閉鍵空間通知功能   ############################### ADVANCED CONFIG ###############################   hash-max-ziplist-entries 512 ##filed最多512個   hash-max-ziplist-value 64 ##value最大64位元組   list-max-ziplist-size -2 ##取正值時表示quicklist節點ziplist包含的數據項   list-compress-depth 0 ##0: 是個特殊值,表示都不壓縮   set-max-intset-entries 512 ##如 type 是 REDIS_SET 類型的,如果其值可以表示成數字類型且 entry 小於配置值set-max-intset-entries, 則可以編碼成 REDIS_ENCODING_INTSET 類型存儲,以節約內存; 否則採用 Dict類型來存儲   zset-max-ziplist-entries 128 ##相同的hash列表中,排序列表的元素和長度都不能高於如下值   zset-max-ziplist-value 64   hll-sparse-max-bytes 3000   activerehashing yes ##重建hash表的時候如果內存不足 如果此值設置為no則延時,如果為yes則儘快釋放內存   client-output-buffer-limit normal 000 ##客戶端buffer限制,如果達到硬限制則立刻斷開   client-output-buffer-limit slave 256mb 64mb 60   client-output-buffer-limit pubsub 32mb 8mb 60   hz 10 ##一個任務可以使用的cpu數目   aof-rewrite-incremental-fsync yes ##當一個子進程要改寫AOF文件,如果以下選項啟用,那文件將會在每產生32MB數據時進行同步,這樣提交增量文件到磁盤時可以避免出現比較大的延遲   ########################### ACTIVE DEFRAGMENTATION #######################

8.5配置slave從模式

主從配置文件一樣,從庫只需要加幾個配置即可

 ########################### ACTIVE DEFRAGMENTATION #######################   ################################# REPLICATION #################################   slaveof 172.17.0.53 6306#主服務器redis的ip和端口   masterauth rds6301_paswd   slave-read-only yes

8.6啟動redis實例

 [root@docker-02 redis]# /usr/bin/sudo -H -u redis -g redis /bin/bash -c "/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6301.conf"   [root@docker-02 redis]# ps -ef|grep 6301   redis    32013    1 016:00 ?        00:00:00 /usr/local/redis/bin/redis-server 0.0.0.0:6301   root     3201831963 016:00 pts/0    00:00:00 grep--color=auto 6301

一般redis都是單機多實例部署,只需要替換配置文件中的端口相關的配置即可,

appendonly 和 SNAPSHOTTING 可以都開啟或只開啟一個即可根據實際需求決定 。

8.7查看狀態

 [root@docker-02 bin]# /usr/local/redis/bin/redis-cli -p 6301 -a rds6301_paswd info   ##可以看到從的狀態信息   # Replication   role:slave   master_host:172.17.0.53   master_port:6306   master_link_status:up   master_last_io_seconds_ago:3   master_sync_in_progress:0   slave_repl_offset:718410   slave_priority:100   slave_read_only:1   connected_slaves:0   master_replid:d40bce93544a3a66c6afc01081fe851a4ccf278d   master_replid2:0000000000000000000000000000000000000000   master_repl_offset:718410   second_repl_offset:-1   repl_backlog_active:1   repl_backlog_size:1048576   repl_backlog_first_byte_offset:1   repl_backlog_histlen:718410

9、redis基本操作

 ##登錄到redis   [root@docker-02 ~]# /usr/local/redis/bin/redis-cli -p 6301 -a rds6301_paswd   ##獲取使用幫助   127.0.0.1:6301> help  ##redis的help命令非常強大,因為redis支持眾多的數據結構,每一種數據結構當中都支持N種操作,因此需要使用 help @group方式來1.獲取某一種數據結構所支持的操作2.獲取字符串組所支持有那些操作   127.0.0.1:6301> help @string   ##獲取單個命令的使用方法   127.0.0.1:6301> help APPEND   APPEND key value  ##命令方法   summary: Append a value to a key   since: 2.0.0  ##說明此命令在哪個版本中引入的   group: string  ##該命令所屬哪一個組   ##查看都有哪些組   127.0.0.1:6301> help TAB鍵,每敲一次輪換一個,帶有@則為一個組,不帶@則為命令使用   ##切換庫(名稱空間)   127.0.0.1:6301> select 1 ##表示切換到1號庫中,默認為0號庫,共16個,0-15

10、鍵的遵循

1.可以使用ASCII字符

2.鍵的長度不要過長,鍵的長度越長則消耗的空間越多

3在同一個庫中(名稱空間),鍵的名稱不得重複,如果複製鍵的名稱,實際上是修改鍵中的值

4.在不同的庫中(名稱空間),鍵的同一個名稱可以重複

5.鍵可以實現自動過期

11、Strings的操作

 127.0.0.1:6301[1]> help set   SET key value [EX seconds] [PX milliseconds] [NX|XX]  ##命令 鍵 值 [EX 過期時間,單位秒]   summary: Set the string value of a key   since: 1.0.0   group: string   ##NX:如果一個鍵不存在,才創建並設定值,否則不允許設定   ##XX:如果一個鍵存在則設置鍵的值,如果不存在則不創建並不設置其值   127.0.0.1:6301[1]> setywm lzll   OK   127.0.0.1:6301[1]> setywm aaa NX  ##反回提示一個沒能執行的操作   (nil)   127.0.0.1:6301[1]> getywm   "lzll"   127.0.0.1:6301[1]> setywm abc XX   OK   ##定義一個鍵並設置過期時間為60秒   127.0.0.1:6301[1]> setywm bcd EX 60   OK

12、獲取鍵中的值

 127.0.0.1:6301[1]> help get   GET key   summary: Get the value of a key   since: 1.0.0   group: string   127.0.0.1:6301[1]> setmxp lzll   OK   127.0.0.1:6301[1]> getmxp   "lzll"   ##添加鍵中的值(在原有鍵中附加值的內容)   127.0.0.1:6301[1]> append mxp fda   (integer) 7   127.0.0.1:6301[1]> getmxp   "lzllfda"   ##獲取指定鍵中的值的字符串的長度   127.0.0.1:6301[1]> strlen mxp   (integer) 7

13、定義整數值

 127.0.0.1:6301[1]> setywm 0 ##整數值為0   OK   ##增加鍵中的整數值   127.0.0.1:6301[1]> incr ywm   (integer) 1   127.0.0.1:6301[1]> incr ywm   (integer) 2   127.0.0.1:6301[1]> incr ywm   (integer) 3   127.0.0.1:6301[1]> incr ywm   (integer) 4   127.0.0.1:6301[1]> getywm   "4"   註:incr命令只能對整數使用

14、刪除鍵

 127.0.0.1:6301[1]> del ywm   (integer) 1   127.0.0.1:6301[1]> getywm   (nil)

15、列表的操作

鍵指向一個列表,而列表可以理解為是一個字符串的容器,列表是有眾多元素組成的集合,可以在鍵所指向的列表中附加一個值

1.LPUSH 在鍵所指向的列表前面插入一個值(左邊加入)

2.RPUSH 在鍵所指向的列表後面附加一個值(右邊加入)

3.LPOP 在鍵所指向的列表前面彈出一個值(左邊彈出)

4.RPOP 在鍵所指向的列表後面彈出一個值(右邊彈出)

5LINDEX 根據索引獲取值,指明索引位置進行獲取對應的值

6.LSET 用於修改指定索引的值為指定的值

 ##指定一個新的列表,在幫助中並沒說明哪個命令用於創建一個新的列表,實際上創建一個新的列表使用LPUSH或RPUSH都可以   127.0.0.1:6301[1]> help @list   127.0.0.1:6301[1]> lpush ll cjk  ##ll為列表名稱,cjk為值(索引)   (integer) 1   ##獲取列表中的值:需要指明索引位置進行獲取對應的值   127.0.0.1:6301[1]> lindex ll 0 ##第一個索引則為0   "cjk"   ##在原有的列表中的左側加入一個值   127.0.0.1:6301[1]> lpush ll 0   (integer) 3   127.0.0.1:6301[1]> lpush ll 1   (integer) 4   127.0.0.1:6301[1]> lindex ll 0   "1"   127.0.0.1:6301[1]> lindex ll 1   "0"   ##在原有的列表中的右側加入一個值   127.0.0.1:6301[1]> rpush ll lzll   (integer) 7   127.0.0.1:6301[1]> lindex ll 6   "lzll"   ##修改一個已有的列表中的值   127.0.0.1:6301[1]> lset ll 6abc   OK   127.0.0.1:6301[1]> lindex ll 6   "abc"   ##查看列表中的值的數量   127.0.0.1:6301[1]> llen ll   (integer) 7   ##在已有的列表中右側彈出(刪除)一個值   127.0.0.1:6301[1]> rpop ll   "abc"   ##在已有的列表中左側彈出(刪除)一個值   127.0.0.1:6301[1]> lpop ll   "1"   127.0.0.1:6301[1]> lpop ll   "0"   127.0.0.1:6301[1]> lpop ll   "fda"

16、清空數據庫

 ##FLUSHDB:刪除當前選擇的數據庫所有key   ##FLUSHALL:清空所有庫   127.0.0.1:6301[1]> flushdb   OK