Redis客戶端的使用&Redis其他功能&持久化的取捨和選擇
3. Redis客戶端的使用
3-1 課程目錄
3-2 Java客戶端:Jedis
Jedis是什麼
獲取Jedis
Maven依賴
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
#1.生成一個Jedis對象,這個對象負責和指定Redis節點進行通信Jedis jedis=new Jedis("127.0.0.1",6379);
#2.jedis執行set操作
jedis.set("hello","world");
#3.jedis執行get操作,value="world"
String value=jedis.get("hello");
構造函數常用參數
Jedis(String host,int port,int connectionTimeout,int soTimeout)
·host:Redis節點的所在機器的IP
·port:Redis節點的端口
·connectionTimeout:客戶端連接超時
·soTimeout:客戶端讀寫超時
//1.生成一個Jedis對象,這個對象負責和指定Redis節點進行通信
Jedis jedis = new Jedis("127.0.0.1", 6379);
//1.string
jedis.set("hello","world");
//輸出結果:world jedis.get("hello");
// 輸出結果:1
jedis.incr("counter");
//2.hash
jedis.hset("myhash","f1","v1");
jedis.hset("myhash","f2","v2");
//輸出結果:{f1=v1,f2=v2}
jedis.hgetAll("myhash");
//3.list
jedis.rpush("mylist","1");
jedis.rpush("mylist","2");
jedis.rpush("mylist","3");
///輸出結果:[1,2,3]
jedis.lrange("mylist",0,-1);
//4.set
jedis.sadd("myset","a");
jedis.sadd("myset","b");
jedis.sadd("myset","a");
//輸出結果:[b,a]
jedis.smembers("myset");
//5.zset
jedis.zadd("myzset",99,"tom");
jedis.zadd("myzset",66,"peter");
jedis.zadd("myzset",33,"james");
//輸出結果:[["james"],33.0],[["peter"],66.0],["tom"],99.0]]
jedis.zrangeWithScores("myzset",0,-1);
Jedis連接池使用
◆Jedis直連
◆Jedis連接池
◆方案對比
◆JedisPool使用
public void useJedisPool(){
//初始化Jedis連接池,通常來講JedisPool是單例的。
GenericObjectPoolConfig poolConfig=new GenericObjectPoolConfig();
JedisPool jedisPool =new JedisPool(poolConfig,"127.0.0.1",6379);
Jedis jedis = null;
try {
//1.從連接池獲取jedis對象
jedis = jedisPool.getResource());
//2.執行操作
jedis.set("hello","world");
} catch(Exception e){
e.printStackTrace();
}finally{
if(jedis!=null);
//如果使用JedisPool,close操作不是關閉連接,代表歸還連接池jedis.close0;
}
}
4.瑞士軍刀Redis其他功能
除了5種數據結構外,Redis還提供了諸如慢查詢、Pipeline、Bitmap、HyperLogLog、發佈訂閱、GEO等附加功能,在這些功能的幫助下,Redis的應用場景更加豐富。
4-1 課程目錄
◆慢查詢◆Bitmap
◆pipeline◆HyperLogLog
◆發佈訂閱◆GEO
4-2 慢查詢
◆生命週期
◆兩個配置
slowlog-max-len:但時間達到slowlog-log-slower-than=10000 之後將會認定爲慢查詢,隨後會進入 長度爲slowlog-max-len的隊列
slowlog-log-slower-than: 記錄爲慢查詢的閾值
- 慢查詢閥值(單位:微秒)
- slowlog-log-slower-than=0,記錄所有命令
- slowlog-log-slower-than<0,不記錄任何命令。
配置方法
- 默認值
config get slowlog-max-len=128
config get slowlog-log-slower-than=10000 - 修改配置文件重啓
- 動態配置
config set slowlog-max-len 1000
config set slowlog-log-slower-than 1000
◆三個命令
1.slowlog get[n]:獲取慢查詢隊列
2.slowlog len:獲取慢查詢隊列長度
3.slowlog reset:清空慢查詢隊列
◆運維經驗
- slowlog-max-len不要設置過大,默認10ms,通常設置1ms
- slowlog-log-slower-than不要設置過小,通常設置1000左右。
- 理解命令生命週期。
- 定期持久化慢查詢。
4-3 pipeline
◆什麼流水線
使用流水線大大減少網絡開銷
流水線的作用
兩點注意
1.Redis的命令時間是微秒級別(所以速度的瓶頸在網絡)。
2.pipeline每次條數要控制(網絡)。
◆客戶端實現
Jedis jedis =new Jedis("127.0.0.1",6379);
for(int i=0;i<100;i++){
Pipeline pipeline=jedis.pipelined();
for(int j=i*100; j<(i+1)*100; j++){
pipeline.hset("useHashKey:"+j,"field"+j,"value"+j);
pipeline.syncAndReturnAll();
}
}
◆與原生操作(M命令)對比
Pipeline會被拆分 但依然會保證它的原子性
◆使用建議
- 注意每次pipeline攜帶數據量(數據量過大最好進行拆分)
- pipeline每次只能作用在一個Redis節點上
- M操作與pipeline區別
4-4 發佈訂閱
◆角色
發佈者(publisher)
訂閱者(subscriber)
頻道(channel)
◆模型
◆API
publish
publish channel message
使用示例:
redis> publish sohu:tv "hello world"
(integer)3 #訂閱者個數
subscribe
subscribe [channel] #一個或多個
unsubscribe
unsubscribe [channel]#一個或多個
其他
psubscribe [pattern..…]#訂閱模式。
punsubscribe [pattern..…]#退訂指定的模式。
pubsub channels #列出至少有一個訂閱者的頻道。
pubsub numsub [channel..]#列出給定頻道的訂閱者數量
pubsub numpat #列出被訂閱模式的數量
◆發佈訂閱與消息隊列
有了消息隊列 的不同是訂閱者只能有一個接收到消息 就是在搶奪消息
4-5 bitmap
◆位圖
◆相關命令
setbit key offset value
#給位圖指定索引設置值
演示:
getbit key offset
#獲取位圖指定索引的值
bitcount key[start end]
# 獲取位圖指定範圍(start到end,單位爲字節,如果不指定就是獲取全部)位值爲1的個數
bitop op destkey key[key …]
# 做多個Bitmap的and(交集)、or(並集)、not(非)、xor(異或)
# 操作並將結果保存在destkey中
bitpos key targetBit [start] [end]
#計算位圖指定範圍(start到end,單位爲字節,如果不指定就是獲取全部) 第一個偏移量對應的值等於targetBit的位置
◆獨立用戶統計
◆使用經驗
1.type=string,最大512MB
2.注意setbit時的偏移量,可能有較大耗時
3.位圖不是絕對好。
4-6 hyperloglog
◆新的數據結構?
HyperLogLog
1.基於HyperLogLog算法:極小空間完成獨立數量統計。
2.本質還是字符串。
127.0.0.1:6379>type hyperloglog_key string
◆三個命令
pfadd key element [element..J #向hyperloglog添加元素
pfcount key [key..J #計算hyperloglog的獨立總數
pfmerge destkey sourcekey [sourcekey..J #合併多個hyperloglog
使用demo
- 添加與獲取總數
- 合併多個hyperloglog
◆內存消耗
◆使用經驗
- 是否能容忍錯誤?(錯誤率:0.81%,如下面的語句執行結果會每次都不一樣)
127.0.0.1:6379>pfcount 2016_05_01:unique:ids(integer)
1009838
- 是否需要單條數據?
4-7 geo
◆GEO是什麼
應用場景舉例:可以依據位置信息 來實現例如微信搖一搖的功能 查看附近的酒店 餐館等
◆5個城市經緯度
◆相關命令
geo key longitude latitude member
[longitude latitude member..J
#增加地理位置信息
使用案例:
geopos key member [member..…]
#獲取地理位置信息
演示:
geodist key member1 member2 [unit]
#獲取兩個地理位置的距離
#unit:m(米)、km(幹米)、mi(英里)、ft(尺)
georadius key longitude latitude radiusm|km|ft|mi [withcoord][withdist]
[withhash] [COUNT count] [asc|desc] [store key][storedist key]
georadiusbymember key member radiusm|km|ft|mi [withcoord]
[withdist] [withhash] [COUNT count] [asc|desc][store key] [storedist key]
#獲取指定位置範圍內的地理位置信息集合
withcoord:返回結果中包含經緯度。
withdist:返回結果中包含距離中心節點位置。
withhash:返回結果中包含geohash COUNT count:指定返回結果的數量。
ascldesc:返回結果按照距離中心節點的距離做升序或者降序。
store key:將返回結果的地理位置信息保存到指定鍵。
storedist key:將返回結果距離中心節點的距離保存到指定鍵
使用示例
◆相關說明
- since3.2+ 版本纔會有該功能
- type geokey=zset 數據結構其實是zset
- 沒有刪除API:zrem key member 可以使用zset的刪除語句
5. Redis持久化的取捨和選擇
Redis的持久化功能有效避免因進程退出造成的數據丟失問題,本章將介紹介紹RDB和AOF兩種持久化配置和運行流程,以及選擇策略
5-1 目錄
◆持久化的作用
◆RDB
◆AOF
◆RDB和AOF的抉擇
5-2 持久化的作用
◆什麼是持久化
redis所有數據保持在內存中,對數據的更新將異步地保存到磁盤上。
◆持久化的實現方式
快照
- MySQL Dump
- Redis RDB
寫日誌
- MySQL Binlog
- Hbase HLog
- Redis AOF
5-3 RDB
◆什麼是RDB
◆觸發機制-主要三種方式
save 命令(同步)
由於是同步命令 會造成阻塞
執行該命令的文件策略:如存在老的RDB文件,將進行替換
執行該命令的複雜度O(N)
bgsave命令
使用 fork()創建一個子進程來進行RDB的生成 完成後再通知給主進程
其中使用 fork()速度會更快 但是依然有可能阻塞主線程
執行該命令的文件策略和複雜度與save命令相同
sava與bgsave的不同
自動生成RDB
在seconds時間內 發生 changes 次改變則觸發生成RDB
實際上改方式無法控制生成RDB的一個頻率
配置
save 9001
save 30010
save 6010000
dbfilename dump.rdb #文件名稱
dir./ #相關文件存放位置
stop-writes-on-bgsave-error yes # 如果 bgsave發生了錯誤是否停止寫入
rdbcompression yes # rdb文件是否採用壓縮格式
rdbchecksum yes #是否對rdb文件進行一個檢驗
最佳配置(更改相關參數 對於多臺機器要對文件名稱進行區分 將文件保存在不同的位置)
◆觸發機制-不容忽略方式
- 全量複製
- debug reload:進行一個debug級別的重啓 不需要將內存進行清空 並且在該過程仍會觸發RDB文件的生成
- shutdown : 進行關閉的時候會進行 RDB文件的生成
◆試驗
save阻塞
bgsave fork
真的自動?
RDB長啥樣?
待做。。。。
RDB總結
- RDB是Redis內存到硬盤的快照,用於持久化。
- save通常會阻塞Redis。
- bgsave不會阻塞Redis,但是會fork新進程。
- save自動配置滿足任一就會被執行。
- 有些觸發機制不容忽視
5-4 AOF
◆RDB現存問題
- 耗時、耗性能
- 不可控、丟失數據
◆什麼是AOF
創建過程中將執行的命令保存在AOF中
重啓之後再將AOF載入到Redis當中
◆AOF三種策略
always
always表示每條命令都執行 fsync 學到硬盤中 防止內容丟失
everysec
每秒刷新到硬盤中 可能會丟失一秒的數據
no
由操作系統來決定
三種策略比較
默認使用第二種
◆AOF重寫
過期、重複、沒有用或可優化的命令 進行化簡 從而減少AOP文件
AOF重寫作用:
- 減少硬盤佔用量
- 加速恢復速度
AOF重寫實現兩種方式
bgrewriteaof:類似於 Bgsave命令
AOF重寫配置
需要同時到達如下配置才能夠觸發
·aof_current_size>auto-aof-rewrite-min-size
·aof_current_size-aof_base_size/aof_base_size>auto-
aof-rewrite-percentage
◆AOF的配置
appendonly yes # 打開使用aof
appendfilename #"appendonly-${port}.aof" #配置aof的文件名
appendfsync everysec #AOF策略
dir/bigdiskpath
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
◆實驗
待做。。。。
5-5 RDB和AOF抉擇
◆RDB和AOF比較
◆RDB最佳策略
- “關"
- 集中管理
- 主從,從開?
◆AOF最佳策略
- “開”:緩存和存儲
- AOF重寫集中管理
- everysec
◆最佳策略
- 小分片
- 緩存或者存儲
- 監控(硬盤、內存、負載、網絡)
- 足夠的內存