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