Redis 从入门到起飞(下)
5. keys 命令
5.1 常用命令
-
keys 返回滿足給定pattern 的所有key redis 127.0.0.1:6379> keys mylist*
"mylist"
"mylist5"
"mylist6"
"mylist7"
"mylist8"
-
exists 確認一個key 是否存在 示例:從結果來看,數據庫中不存在HongWan 這個key,但是age 這個key 是存在的 redis 127.0.0.1:6379> exists HongWan (integer) 0 redis 127.0.0.1:6379> exists age (integer) 1 redis 127.0.0.1:6379>
-
del 刪除一個key redis 127.0.0.1:6379> del age (integer) 1 redis 127.0.0.1:6379> exists age (integer) 0
-
rename 重命名key 示例:age 成功的被我們改名為age_new 了 redis 127.0.0.1:6379[1]> keys *
"age" redis 127.0.0.1:6379[1]> rename age age_new OK redis 127.0.0.1:6379[1]> keys *
"age_new" redis 127.0.0.1:6379[1]>
-
type 返回值的類型 示例:這個方法可以非常簡單的判斷出值的類型 redis 127.0.0.1:6379> type addr string redis 127.0.0.1:6379> type myzset2 zset redis 127.0.0.1:6379> type mylist list redis 127.0.0.1:6379>
?
5.2 設置 key 的生存時間
Redis在實際使用過程中更多的用作緩存,然而緩存的數據一般都是需要設置生存時間的,即:到期后數據銷毀。
| EXPIRE key seconds | 設置key的生存時間(單位:秒)key在多少秒后會自動刪除 |
| TTL key | 查看key剩余的生存時間 |
| PERSIST key | 清除生存時間 |
| PEXPIRE key milliseconds | 生存時間設置單位為:毫秒 |
例子:
192.168.101.3:7002>?set?test?1????????設置test的值為1 OK 192.168.101.3:7002>?get?test????????????獲取test的值 "1" 192.168.101.3:7002>?EXPIRE?test?5????設置test的生存時間為5秒 (integer)?1 192.168.101.3:7002>?TTL?test????????????查看test的生于生成時間還有1秒刪除 (integer)?1 192.168.101.3:7002>?TTL?test (integer)?-2 192.168.101.3:7002>?get?test????????????獲取test的值,已經刪除 (nil)?
6. Redis 持久化方案
6.1 Rdb 方式
Redis 默認的方式,redis 通過快照方式將數據持久化到磁盤中。
6.1.1 設置持久化快照的條件
在 redis.conf 中修改持久化快照的條件:
6.1.2 持久化文件的存儲目錄
在 redis.conf 中可以指定持久化文件的存儲目錄
?
6.1.3 Rdb 的問題
一旦redis非法關閉,那么會丟失最后一次持久化之后的數據。
如果數據不重要,則不必要關心。 如果數據不能允許丟失,那么要使用 aof 方式。
?
6.2 Aof 方式
Redis 默認是不使用該方式持久化的。Aof 方式的持久化,是操作一次 redis 數據庫,則將操作的記錄存儲到 aof 持久化文件中。
-
第一步:開啟 aof 方式持久化方案。 將redis.conf中的appendonly改為yes,即開啟aof方式的持久化方案。
?
-
Aof文件存儲的目錄和rdb方式的一樣。 Aof文件存儲的名稱
?
在使用aof和rdb方式時,如果redis重啟,則數據從aof文件加載。
?
7. Redis 的主從復制
7.1 什么是主從復制
持久化保證了即使redis服務重啟也不會丟失數據,因為redis服務重啟后會將硬盤上持久化的數據恢復到內存中,但是當redis服務器的硬盤損壞了可能會導致數據丟失,如果通過redis的主從復制機制就可以避免這種單點故障,如下圖:
說明:
-
主redis中的數據有兩個副本(replication)即從redis1和從redis2,即使一臺redis服務器宕機其它兩臺redis服務也可以繼續提供服務。
-
主redis中的數據和從redis上的數據保持實時同步,當主redis寫入數據時通過主從復制機制會復制到兩個從redis服務上。
-
只有一個主redis,可以有多個從redis。
-
主從復制不會阻塞master,在同步數據時,master 可以繼續處理client 請求
-
一個redis可以即是主又是從,如下圖:
?
7.2 主從復制設置
7.2.1 主機配置
無需配置
7.2.2 從機配置
-
第一步:復制出一個從機?cp bin/ bin2 -r
-
第二步:修改從機的 redis.conf 語法:slaveof masterip masterport slaveof 192.168.242.137 6379
?
-
第三步:修改從機的 port 地址為 6380
?
-
第四步:清除從機的持久化文件?rm -rf appendonly.aof dump.rdb
-
第五步:啟動從機?./redis-server redis.conf
-
第六步:啟動6380的客戶端?./redis-cli -p 6380
注意:?主機一旦發生增刪改操作,那么從機會將數據同步到從機中 從機不能執行寫操作
?
8. Redis 集群
8.1 redis-cluster 架構圖
架構細節: (1)所有的redis節點彼此互聯(PING-PONG機制),內部使用二進制協議優化傳輸速度和帶寬. (2)節點的fail是通過集群中超過半數的節點檢測失效時才生效. (3)客戶端與redis節點直連,不需要中間proxy層.客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可 (4)redis-cluster把所有的物理節點映射到[0-16383]slot上,cluster 負責維護node<->slot<->value Redis 集群中內置了 16384 個哈希槽,當需要在 Redis 集群中放置一個 key-value 時,redis 先對 key 使用 crc16 算法算出一個結果,然后把結果對 16384 求余數,這樣每個 key 都會對應一個編號在 0-16383 之間的哈希槽,redis 會根據節點數量大致均等的將哈希槽映射到不同的節點.
?
8.2 redis-cluster 投票 容錯
?
(1)集群中所有master參與投票,如果半數以上master節點與其中一個master節點通信超過(cluster-node-timeout),認為該master節點掛掉. (2):什么時候整個集群不可用(cluster_state:fail)?
-
如果集群任意master掛掉,且當前master沒有slave,則集群進入fail狀態。也可以理解成集群的[0-16383]slot映射不完全時進入fail狀態。
-
如果集群超過半數以上master掛掉,無論是否有slave,集群進入fail狀態。
?
8.3 安裝 Ruby
集群管理工具(redis-trib.rb)是使用 ruby 腳本語言編寫的。
-
安裝 ruby
-
上傳 redis-3.0.0.gem 到 linux
-
安裝 ruby 和 redis 接口?gem install redis-3.0.0.gem
-
將 redis-3.0.0 包下 src 目錄中的以下文件拷貝到 redis/redis-cluster/
?
8.4 搭建集群
搭建集群最少需要 3 臺主機,如果每臺主機再配置一臺從機的話,則最少需要6臺機器。 端口設計:7001-7006
復制出一個7001機器?cp bin ./redis-cluster/7001 -r
如果存在持久化文件,則刪除?rm -rf appendonly.aof dump.rdb
設置集群參數,修改redis.conf
?
修改端口
?
復制出7002-7006機器
修改7002-7006機器端口
創建文件 start-all.sh
-
修改文件權限
-
執行文件,啟動六臺機器
-
創建集群?./redis-trib.rb create --replicas 1 192.168.126.128:7001 192.168.126.128:7002 192.168.126.128:7003 192.168.126.128:7004 192.168.126.128:7005 192.168.126.128:7006
?
8.5 連接集群
root@ubuntu:/usr/local/redis/redis-cluster/7001#?./redis-cli?-p?7001?-c
-c 指定集群連接
?
8.6 查看集群信息
-
查看集群信息
192.168.126.128:7002>?cluster?info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:2 cluster_stats_messages_sent:260 cluster_stats_messages_received:260 -
查看集群節點
192.168.126.128:7002>?cluster?nodes 3a15e73dacb512745156535ae7f959acf65ae12e?192.168.126.128:7005?slave?23e173cdc0b7673dc28cae70efaabbc41308bfdc?0?1531452321139?5?connected 2a58a53a5b10f7bd91af04128a6ed439d534c0ee?192.168.126.128:7001?master?-?0?1531452322145?1?connected?0-5460 d0808388485dd08f1a2ecdfe3d2b213742d0050d?192.168.126.128:7004?slave?2a58a53a5b10f7bd91af04128a6ed439d534c0ee?0?1531452318117?4?connected 23e173cdc0b7673dc28cae70efaabbc41308bfdc?192.168.126.128:7002?myself,master?-?0?0?2?connected?5461-10922 2af2312acc56552f9f73470f90d9a51973fc74d3?192.168.126.128:7006?slave?78faf92cfdbd12e1b27b270fb0798e67017f4d0b?0?1531452320132?6?connected 78faf92cfdbd12e1b27b270fb0798e67017f4d0b?192.168.126.128:7007?master?-?0?1531452319123?3?connected?10923-16383
?
8.7 jedis連接集群
@Testpublic?void?jedisCluster()?{//?創建jedisClusterSet<HostAndPort>?nodes?=?new?HashSet<>();nodes.add(new?HostAndPort("192.168.242.137",?7001));nodes.add(new?HostAndPort("192.168.242.137",?7002));nodes.add(new?HostAndPort("192.168.242.137",?7003));nodes.add(new?HostAndPort("192.168.242.137",?7004));nodes.add(new?HostAndPort("192.168.242.137",?7005));nodes.add(new?HostAndPort("192.168.242.137",?7006));nodes.add(new?HostAndPort("192.168.242.137",?7007));JedisCluster?cluster?=?new?JedisCluster(nodes);cluster.set("s4",?"444");String?result?=?cluster.get("s4");System.out.println(result);cluster.close();}
?
8.8 使用 spring
配置 applicationContext.xml
<!--?連接池配置?--> <bean?id="jedisPoolConfig"?class="redis.clients.jedis.JedisPoolConfig"><!--?最大連接數?--><property?name="maxTotal"?value="30"?/><!--?最大空閑連接數?--><property?name="maxIdle"?value="10"?/><!--?每次釋放連接的最大數目?--><property?name="numTestsPerEvictionRun"?value="1024"?/><!--?釋放連接的掃描間隔(毫秒)?--><property?name="timeBetweenEvictionRunsMillis"?value="30000"?/><!--?連接最小空閑時間?--><property?name="minEvictableIdleTimeMillis"?value="1800000"?/><!--?連接空閑多久后釋放,?當空閑時間>該值?且?空閑連接>最大空閑連接數?時直接釋放?--><property?name="softMinEvictableIdleTimeMillis"?value="10000"?/><!--?獲取連接時的最大等待毫秒數,小于零:阻塞不確定的時間,默認-1?--><property?name="maxWaitMillis"?value="1500"?/><!--?在獲取連接的時候檢查有效性,?默認false?--><property?name="testOnBorrow"?value="true"?/><!--?在空閑時檢查有效性,?默認false?--><property?name="testWhileIdle"?value="true"?/><!--?連接耗盡時是否阻塞,?false報異常,ture阻塞直到超時,?默認true?--><property?name="blockWhenExhausted"?value="false"?/> </bean> <!--?redis集群?--> <bean?id="jedisCluster"?class="redis.clients.jedis.JedisCluster"><constructor-arg?index="0"><set><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7001"></constructor-arg></bean><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7002"></constructor-arg></bean><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7003"></constructor-arg></bean><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7004"></constructor-arg></bean><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7005"></constructor-arg></bean><bean?class="redis.clients.jedis.HostAndPort"><constructor-arg?index="0"?value="192.168.101.3"></constructor-arg><constructor-arg?index="1"?value="7006"></constructor-arg></bean></set></constructor-arg><constructor-arg?index="1"?ref="jedisPoolConfig"></constructor-arg> </bean>測試代碼
private?ApplicationContext?applicationContext;@Beforepublic?void?init()?{applicationContext?=?new?ClassPathXmlApplicationContext("classpath:applicationContext.xml");}//?redis集群@Testpublic?void?testJedisCluster()?{JedisCluster?jedisCluster?=?(JedisCluster)?applicationContext.getBean("jedisCluster");jedisCluster.set("name",?"zhangsan");String?value?=?jedisCluster.get("name");System.out.println(value);}?
總結
以上是生活随笔為你收集整理的Redis 从入门到起飞(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis 从入门到起飞(上)
- 下一篇: 你们都在用IntelliJ IDEA吗?