資料存儲類型介紹
業務資料的特殊性
作為緩存使用
- 原始業務功能設計
- 秒殺
- 618活動
- 雙11活動
- 12306
附加功能
- 系統功能優化更新
- 單伺服器更新叢集
- session管理
- Token管理
Redis資料類型(5種常用)
- string string
- hash HashMap
- list LinkedList
- set HashSet
- sorted_set TreeSet
string
- get key
- set key
- del [key]
- mset key1 value1 key2 value2
- mget key1 key2
- strlen key
- append key value
單資料操作與多資料操作的選擇之或?
- 比較發送與執行時間消耗時間對比
string資料類型的擴充操作
- 設定數值資料新增加指定範圍的值,可以使用負号作為遞減操作
-
incr key incrby key increment incrbyfloat key increment
- 設定數值資料新減去指定範圍的值
-
decr key decrby key increment
- 設定數值有效期 解決時效性控制的操作
-
setex key second value 秒 psetex key milliseconds value 毫秒
string類型資料操作時的注意事項
- 設定數值有效期 解決時效性控制的操作
- 資料未擷取到
-
(nil)等于 null
- 資料最大存儲量
512m
- 資料計算最大範圍 (java中的long的最大值)
9223372036854775807
- 資料最大存儲量
string類型應用場景
- 在redis中存儲使用者資訊
- user🆔333:fans -> 11111 數值
- user🆔333 -> {id:333,fans:333} json
- redis應用于各種結構性和非結構性高熱度資料通路的加速
- key的設定約定 表名:主鍵名:主鍵值:字段名
hash 底層使用哈希表結構存儲
底層使用哈希表結構存儲
hash存儲結構優化
- 如果field字段數量少,使用資料數組進行存儲
- 如果field字段數量多,存儲結構使用hashmap
hash類型資料的基本操作
- 添加/修改資料
-
hset key field value
- 擷取資料
-
hget key field hgetall key
- 删除資料
-
hdel key field [field2]
- 添加/修改多個資料
-
hmset key field1 value1 field2 value2
- 擷取多個資料
-
hmget key filed1 field2
- 擷取hash表中字段的數量
-
hlen key
- 擷取hash表中是否存在指定字段
-
hexists key field
hash資料類型的擴充操作
- 擷取hash表中所有的字段名和值
-
hkeys key hvalues key
- 設定值自增
-
hincrby key increment hincrbyfloat key increment
- 設定值字元,存在則設定失敗,不存在則設定成功
-
setnx key field value
hash資料類型注意事項
- hash類型value隻能存字元串
- 每個hash可以存儲2^32-1個鍵值對
- hash可以靈活操作屬性,雖然可以作為對象使用,但是不能濫用
- hgetall key 擷取hash内的鍵值對
hash資料類型應用場景
- 購物車
list
list類型資料的基本操作 連結清單
- 添加/修改資料
-
lpush key value [value] rpush key value [value]
- 擷取資料
-
lrange key start stop (0,-1擷取全部) lindex key index llen key
- 擷取并移除資料
-
lpop key rpop key
- 規定時間内擷取并移除資料
-
blpop key [key] timeout (機關為秒) brpop key [key] timeout (機關為秒)
業務場景
- 删除指定元素
-
lrem key count value
list資料類型注意事項
- list資料儲存的資料都是string類型,最多2^32-1個元素
- list常被用作隊列
- list結束索引為-1
- list可以進行資料分頁操作 第一頁來自list,第二頁及更多來自資料庫
業務場景
- 資訊管理
- 多路資訊彙總
- 最新消息
set 無序
set類型資料的基本操作
- 添加資料
-
sadd key memeber1 [member]
- 擷取全部資料
-
smembers key
- 删除資料
-
srem key member1 [member]
set類型資料的擴充操作
- 随機擷取幾個元素
-
srandmember key count
- 随機擷取幾個元素 并删除
-
spop key count
- 擷取元素個數
-
scard key
- 求兩個集合的交并差
-
sinter key key2 sunion key1 key2 sdiff key1 key2
- 求兩個集合的交并差 并存到指定集合
-
sinterstore desc key key2 sunionstore desc key1 key2 sdiffstore desc key1 key2
- 将指定資料從原始集合移動到目标集合中
-
smove source desc member
- 檢視資料是否存在
-
sismember key memeber
業務場景
- 随機推薦和抽獎等
zset 有序
zset類型資料的基本操作
- 添加資料
-
zadd key score memeber1
- 查詢
-
zrange key start stop [withscores]
- 查詢 反序
-
zrevrange key start stop [withscores]
- 删除
-
zrem key memeber [member]
資料類型實戰
- 限流 如果限流為100 則把最大值-100,利用異常做限制,不需要每次進行判斷
通用指令
- 删除key del key
- key的類型 type key
- key是否存在 exists key
- 為key設定有效期
-
expire key seconds pexpire key millseconds expireeat key timestamp pexpireeat key mill-timestamp
- 擷取key有效時間
-
ttl key pttl key
- 切換key從臨時轉為永久
-
persist key
- 查詢模式
-
keys * 比對所有 keys ?lezai 比對單個字元 keys a[abc] 比對aa ab ac
- key重命名
-
rename key new key renamenx key newkey 新key不存在則成功
- 對所有key 裡面的内容排序
-
sort key
- 切換資料庫
-
select dbindex ping pong
- 資料庫移動
-
mv key dbindex flushdb 删除目前庫資料 flushall 清除所有資料
Jedis
- 用戶端連接配接redis
-
連接配接 Jedis jedis =new Jedis("127.0.0.1",6379) 設定 jedis.set("name",123) 擷取 jedis.get("name")
Linux安裝redis
- 下載下傳 wget http://download.redis.io/releases/redis-4.0.10.tar.gz
- 解壓 tar-xvzf redis-4.0.10.tar.gz
- 編譯 make
- 安裝make install
- 指定端口啟動 redis-server --port 9999
- 指定端口連接配接 redis-cli -p 9999
- 指定配置檔案啟動 redis-server conf/redis.conf
redis服務端基本配置
- daemonize yes 以守護程序方式啟動
- port 6379 設定啟動端口
- dir “/redis/data” 設定目前服務檔案儲存位置
- logfile “744.log” 設定日志檔案名
持久化
RDB
- save 手動執行儲存一次快照資訊
- 相關配置
-
dbfilename dump.rdb 設定本地資料庫檔案 預設為dump.rdb 一般設定為 dump-端口号.rdb rdbcompression yes 是否啟動壓縮 rdbchecksum yes 是否對庫檔案進行校驗
- bgsave 使用fork函數生成一個子程序,在子程序中執行
- rdb自動啟動定時儲存
-
配置資訊 save second changenum save 900 1 900 秒内有一個key變化 save 60 3 60秒内有3個key變化 save 10 6
AOF
寫資料的三種政策
- always 每次操作都同步寫入到aof中,資料零誤差 性能低
- everysec 每秒 将緩沖區的指令同步到aof中,系統當機隻會丢失一秒的資料
- no 系統控制 不可控
AOF功能開啟
- appendonly yes | no 開啟持久化 預設不開啟
- appendfsync always | everysec | no AOF政策
- appendfilename fielname
AOF重寫 重寫規則
- 程序内已逾時的資料不再重寫
- 忽略無效指令
- 對同一資料的多條寫合并為一條
- bgrewriteaof 重寫aof指令
AOF 與RDB 選擇
- 資料很敏感 使用aof
- 資料間斷性呈現 RDB
- 綜合方案 同時開啟rdb+aof
Redis進階操作
Redis事務
事務的基本操作
- 開啟事務
-
multi 設定事務的開啟 執行指令後,全都加入到事務中
- 執行事務
-
exec 設定事務的結束,同時執行事務,與multi成對出現
- 取消事務
-
discard 取消事務
- 注意
-
事務出錯不能復原,産生的資料不會復原
鎖
- watch key1 key2 …
-
監控某個key,需要在事務外面使用,如果key被外部修改了,則終止事務的執行
- unwatch
-
取消對事務的監控
分布式鎖
- setnx key value
解決死鎖 添加時效性
Redis删除政策
定時删除
- 建立一個定時器,當key設定有過期時間,且過期時間到達,由定時器執行對鍵的删除操作
- 犧牲CPU保證記憶體空間 CPU空閑 記憶體緊張
惰性删除
- 在擷取資料的時候,如果未過期,傳回資料,過期了,删除,傳回不存在
- 犧牲存儲保證CPU 存儲空間足 CPU緊張
定期删除
定期删除政策是怎麼實作的?通過activeExpireCycle函數,serverCron函數執行時,activeExpireCycle函數就會被調用,規定的時間裡面分多次周遊伺服器的expires字典随機檢查一部分key的過期時間,并删除其中的過期key
例如Redis每秒處理:
- 測試随機的20個keys進行相關過期檢測。
- 删除所有已經過期的keys。
- 如果有多于25%的keys過期,重複步奏1.
Redis逐出算法
- 在執行每一個指令前,都調用freememoryifneed,記憶體不足,需要臨時删除一些資料清理空間
- maxmemory 最大記憶體
- maxmemory-samples 随機選擇
- maxmemory-policy
- 有效期的資料
-
volatile-lru 最近最少使用
-
volatile-lfu 最近使用次數最少
-
volatile-ttl 挑選将要過期的資料
-
volatile-random 任意選擇資料淘汰
- 所有資料
-
allkeys-lru 最近最少使用
-
allkeys-lfu 最近使用次數最少
-
allkeys-random 任意選擇資料淘汰
- no-enviction
進階資料類型
bitmaps
- setbits key offset value
- getbits key offset
- bitop [and or not xor] destkey key1 key2 對多個key組合操作,儲存到destkey中
- bitcount key [start end] 統計為1的數量
HyperLogLog
- pfadd key element …
- pfcount key
- pfmerge destkey sourcekey1 sourcekey2
- 相關說明
-
用于基數統計,不是集合,不儲存資料,隻記錄數量而不是具體資料
-
核心是基數估算,最終數值存在一定誤差
-
誤差範圍:0.81%
-
占用12k
-
pfadd 不是一次性配置設定12看,而是随基數增大而增加空間
Geo 距離計算
- geoadd key longitude latitude member … 添加坐标
- geopos key member … 擷取坐标
- geodist key member1 member2 unit 擷取坐标點距離
- georadius key longitude latitude radius unit 根據坐标求範圍内的資料
- georadiusbymember key memeber radius unit 根據點求範圍内的資料
Redis叢集
主從複制簡介
網際網路“三高”
- 高性能
- 高并發
- 高可用 5個9 99.999%
工作流程
- 建立連接配接
- 資料同步(複制資料)
- 反複同步(指令傳播)
- 建立連接配接階段工作流程
-
1. 發送指令 slaveof ip port
-
2. 接收到指令,響應對方
-
3.儲存master的ip與端口 masterip masterport
-
4.根據連接配接儲存的資訊建立與master的socket
-
5.向master周期發送ping,master相應pong
-
6.slave 發送author password
-
7.驗證授權
-
8.發送指令replyconfiglistening-port port-num
-
9.儲存slave端口号
- 連接配接的三種方式
-
1.slaveof if ip port
-
2.slave啟動時 帶參數 --slaveof masterip masterport
-
3.伺服器配置 slaveof if ip port
- 資料同步階段
-
全量複制開始
-
①發送指令 psync2 請求同步資料
-
②master執行bgsave
-
③第一個slave建立連接配接,建立指令緩沖區
-
④生成rdb,通過socket發給slave
-
⑤vslave接受rdb,清空資料,執行rdb檔案恢複
-
⑥發送指令,告知已經恢複完成
-
全量複制結束
-
部分複制開始
-
⑦發送複制緩沖區指令資訊
-
⑧接受指令,執行bgrewriteeaof,恢複資料
-
部分複制結束
- 指令傳播階段
-
複制緩沖區 偏移量 位元組值
-
工作原理: 通過offset區分不同的slave目前資料傳播的差異,maste記錄已發送的資訊對應的offset,slave記錄已經接受的offset
資料同步(全)
- slave 發送指令 psync ?-1
- master收到發現沒有偏移量,則使用bgsave生成rdb檔案,記錄目前的複制偏移量offset
- 發送fullresync runid offset,通過socket發送給slave,期間收到用戶端指令,offset發生變化
- 收到 + fullresync 儲存master的runid和offset,清空目前資料,接受rdb檔案,執行恢複
- 發送指令 psync2 runid offset
- master接受到指令,判定runid是否比對,判定offset是否在緩沖中
- 如果runid和offset不比對,則執行全量複制
- 如果runid和master校驗通過,offset和offset相同,忽略
- 如果runid和master校驗通過,offset和offset不相同, 發送continue offset,通過socket發送緩沖區中offset到offset的資料
- slave接收到continue,儲存master的offset,接受資訊後,執行bgrewriteaof,恢複資料
- 主從複制參數注意
-
① slave-server-stable-data yes|no 同步過程,開啟或關閉對外寫操作
-
②repl-backlog-size 1mb 設定master指令緩沖區大小,
-
主從複制常見問題
頻繁全量複制
-
①緩沖區太小 導緻offset不比對 解決:緩沖區設定大點
-
頻繁網絡中斷②maset當機重新開機,導緻runid和offset丢失,全量複制 master執行shutdown 時,将runid和offset進行儲存,重新開機時進行讀取
資料不一緻① 執行指令一直阻塞耗時 設定逾時時間
哨兵簡介
哨兵是一個分布式系統,用于對主從結構中的每台伺服器做監控,當出現故障通過投票随機選擇新的master并将所有的slave連接配接到資訊master
作用
- 監控
- 通知
- 自動故障轉移
啟用哨兵模式
- 啟動哨兵
-
redis-sentinel redis-sentinel.conf
-
配置檔案中配置 主redis節點
哨兵工作原理
監控階段
- 用于同步各個節點的狀态資訊
- 擷取sentinel的狀态(是否線上)
- 擷取master狀态
- 擷取所有slave狀态
- master儲存sentinel資訊,作用是讓其他sentinel來發現其他的sentinel,建立訂閱通道
通知階段
- 每個sentinel進行互通
故障轉移階段
- sentinel發現master關挂了,标記master為主觀下線,然後發送指令給奇特哨兵,其他哨兵也會去看看狀态,如果一半以上的哨兵認為master挂了,那就直接标記為客觀下線,執行故障轉移操作
- sentinel通過競選,然後獲得此次處理master的權利,成為領頭sentinel
- 去除不線上的
- 去除響應慢的
- 與原master斷開時間久的
- 優先原則
- 優先級
- offset
- runid
- 發送指令
- 向新的master發送slave no one指令
- 向其他slave發送slaveof新的ip端口
叢集簡介
資料存儲設計
- 通過算法設計,計算出key應該儲存的位置
- 将所有的存儲空間分割成16384份,每台主機儲存一部分代表的是一個存儲空間,不是一個key的儲存空間
- 将key按照計算的結果放到對應的存儲空間
叢集内部通訊設計
- 各個節點互相通信,儲存各個庫中槽的編号資料
- 一次命中,直接傳回
- 一次未命中,告知具體位置
環境搭建
- cluster-enabled yes
- cluster-config-file node-6379.conf
- cluster-node-timeout 10000
- 在src下執行
-
./redis-trib.rb create --replicas 1(一個master,一個slave,2 一個master兩個slave) 主[...] 從[...]
- 連接配接叢集用戶端
-
redis-cli -c
企業級解決方案
緩存預熱
系統啟動前,提前将相關的緩存資料直接加載到緩存系統,避免在使用者請求的時候,先查詢資料庫,然後再将資料緩存的問題,使用者直接查詢事先被預熱的資料
緩存雪崩
緩存擊穿
緩存穿透
解決方案
- 緩存null
- key加密
- 實時監控
- 白名單政策 bitmaps(效率低)