成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Redis學(xué)習(xí)

miguel.jiang / 831人閱讀

摘要:單線程執(zhí)行命令。文件描述符事件。內(nèi)部原因不合理使用或數(shù)據(jù)結(jié)構(gòu)可能由此導(dǎo)致慢查詢等飽和是單線程,只會使用單個持久化阻塞操作產(chǎn)生阻塞,對硬盤的操作產(chǎn)生阻塞或?qū)懖僮髯枞?。?nèi)存達(dá)到時執(zhí)行內(nèi)存溢出控制策略。

最近在看《Redis開發(fā)與運(yùn)維》,把自己學(xué)會的知識點(diǎn)記錄下來,畢竟好記性不如爛筆頭。

一.Redis是什么。

Redis是一個Key-Value的NoSQL數(shù)據(jù)庫.

二.Redis的特點(diǎn)。

1.支持的數(shù)據(jù)類型:hash,list,set,zset,string(memacached只支持string)。

2.單線程執(zhí)行命令。因?yàn)槭菃尉€程,所以減少了線程上下文切換的開銷,同時如果一個命令執(zhí)行時間過長就會引起阻塞。

3.數(shù)據(jù)持久化到內(nèi)存中,一定時間后會存儲到硬盤中。

三.操作數(shù)據(jù)的命令
1.常用的命令

命令 含義
keys * 查看全部的鍵,會遍歷Redis所有的鍵,時間復(fù)雜度是O(n)
scan cursor match pattern 遍歷鍵,cursor是游標(biāo)
type key 查看鍵的類型,key是鍵的名稱
dbsize 查看鍵的數(shù)量:dbsize 是直接獲取Redis內(nèi)置的鍵總量,時間復(fù)雜度是O(1)
exists key 判斷某個鍵是否存在,存在返回1,不存在返回0.
del key[ key...] 返回成功刪除鍵的個數(shù)
expire key time 設(shè)置鍵的過期時間
ttl key 查詢某個鍵的剩余過期時間
object encoding key 查詢鍵的內(nèi)部編碼
rename key newkey 鍵重命名
renamenx key newkey 當(dāng)newkey不存在,鍵重命名成功
randomkey 隨機(jī)選擇一個鍵
persist key 清除鍵的過期時間
move key db 在Redis內(nèi)部進(jìn)行數(shù)據(jù)庫遷移
dump + restore 在不同Redis實(shí)例間遷移數(shù)據(jù)
migrate 在數(shù)據(jù)庫實(shí)例間遷移數(shù)據(jù)

2.操作String數(shù)據(jù)類型的命令

注意:操作String數(shù)據(jù)類型的命令基本以s作為前綴開頭

命令 含義
set key value 插入鍵值對,key是鍵,value是值
get key 查看鍵的值
del key 刪除鍵
setnx key value 當(dāng)key不存在時,設(shè)置值
setex key seconds value seconds是過期時間,設(shè)置鍵值對
mset key value[key value..] 批量獲取值
mget key [key ...] 批量獲取值
incr key 對值做自增1
decr key 對值做自減1
incrby key incrment 自增指定的數(shù)目 increment 數(shù)字
decrby key incrment 自減指定的數(shù)目 increment 數(shù)字
incrbyfloat key incrment 自增指定的浮點(diǎn)數(shù) increment 數(shù)字

內(nèi)部編碼有三種:int,embstr和raw

使用場景:

setnx和setex可用于分布式鎖

incr等可以用于計(jì)數(shù)

統(tǒng)一管理用戶的session

3.操作hash數(shù)據(jù)類型的命令

注意:操作hash數(shù)據(jù)類型的命令基本以h作為前綴開頭

命令 含義
hset key field value 設(shè)置hash的內(nèi)容key=[{field:value}{field:value}]
hget key field 獲取字段值
hdel key field 刪除字段值
hlen key 獲取key的字段數(shù)
hmset key field value [field value...] 批量設(shè)置key的field-value
hmget key field1[field2...] 批量獲得key的field的字段值
hexists key field 判斷key的field是否存在
hkeys key 獲取key的全部字段
hvals key 獲取key的全部value值
hgetall key 獲取key的全部field,value
hincrby key field incrment key的字段field自增increment
hincrbyfloat key field increment key的字段field自增浮點(diǎn)數(shù)increment
hstrlen key field 計(jì)算field的value的長度

內(nèi)部編碼:ziplist和hashtable

4.操作list數(shù)據(jù)類型的命令

注意:操作list數(shù)據(jù)類型的命令基本以l或r或b作為前綴開頭

命令 含義
rpush key value[value...] 從列表右邊添加元素
lpush key value[value...] 從列表左邊添加元素
lrange key start end 獲取指定索引范圍的元素,0表示第一個,-1表示最后一個
linsert key before/after pivot value 在pivot元素前/后插入value元素
lindex key index 獲取列表指定下標(biāo)的元素
llen key 獲取列表的長度
lpop key 從列表的左側(cè)彈出元素
rpop key 從列表的右側(cè)彈出元素
lrem key count value 從左到右刪除count個值為value的元素
lset key index value 設(shè)置index位置的值
brpop/blpop key timeout 阻塞彈出,timeout是超時時間,0表示一直等待下去

內(nèi)部編碼:ziplist(壓縮列表),linkedlist(鏈表)和quicklist

使用場景:

lpush+brpop=阻塞隊(duì)列(消息隊(duì)列)。

lpush+lpop=Stack(棧)

lpush+rpop=Queue(隊(duì)列)

lpush+ltrim=Capped Collection(有限集合)

5.操作set數(shù)據(jù)類型的命令

注意:操作set數(shù)據(jù)類型的命令基本以s作為前綴開頭

命令 含義
sadd key element[element...] 添加元素
srem key element[element...] 刪除元素
scard key 計(jì)算元素個數(shù)
sismember key element 判斷element元素是否在集合中
srandmember key [count] 隨機(jī)生成count個元素,默認(rèn)是1個
spop key 隨機(jī)彈出一個元素
smembers key 查詢?nèi)康脑?/td>
sinter key [key...] 查詢多個集合的并集
sunion key [key...] 查詢多個集合的交集
sdiff key [key...] 查詢多個集合的差集
sinterstore destination key [key...] 查詢多個集合的并集,存儲到destination中
sunionstore destination key [key...] 查詢多個集合的交集,存儲到destination中
sdiffstore destination key [key...] 查詢多個集合的差集,存儲到destination中

內(nèi)部編碼:intset,hashtable

使用場景:

sadd=Tagging(標(biāo)簽)

spop/srandmember=Random item(隨機(jī)數(shù)抽獎)

sadd+sinter=Social Graph(社交需求)

6.操作zset數(shù)據(jù)類型的命令

注意:操作zset數(shù)據(jù)類型的命令基本以z作為前綴開頭

命令 含義
zadd key score memeber[score memeber...] 添加成員
zcard key 計(jì)算成員個數(shù)
zscore key member 計(jì)算成員的分?jǐn)?shù)
zrank/zrevrank key member 計(jì)算成員的排名
zrem key member[member...] 刪除成員
zincrby key increment member 增加成員的分?jǐn)?shù)
zrange/zrevrange key start end [withscores] 從低到高,返回指定排名范圍的成員
zrangebyscore key min max [withscores] [limit offset count] 從低到高,返回指定分?jǐn)?shù)范圍的成員
zrevrangebyscore key max min [withscores] [limit offset count] 返回指定分?jǐn)?shù)范圍的成員
zcount key min max 返回指定范圍的成員個數(shù)
zremrangebyrank key start end 刪除指定排名內(nèi)的升序元素
zremrangebyscore key min max 刪除指定分?jǐn)?shù)范圍的成員
zinterstore destination numberkeys key [key...] [weights weight [weight...]] [aggregate sum/min/max] 兩個有序集合的交集,numberkeys指有序集合進(jìn)行交集的個數(shù)
zunionstore destination numberkeys key [key...] [weights weight [weight...]] [aggregate sum/min/max] 兩個有序集合的并集,numberkeys指有序集合進(jìn)行并集的個數(shù)

內(nèi)部編碼:ziplist(壓縮列表)和skiplist(跳躍表)

使用場景:

排行榜(點(diǎn)贊)

7.Jedis對五種數(shù)據(jù)類型的操作

Jedis jedis = null;
try {
            
    jedis = new Jedis("127.0.0.1", 6379, 10000);
            
    //1.string
    String result1 = jedis.set("string1", "value1");
    String result2 = jedis.get("string1");
    System.out.println(result1);//OK
    System.out.println(result2);//value1
            
    //2.list
    long result3 = jedis.lpush("list1", "math","math","score","score","name","xiaoming");
    List result4 = jedis.lrange("list1", 0, -1);
    System.out.println(result1);//OK
    System.out.println(result4);//xiaoming, name, score, score, math, math
            
    //3.hash
    jedis.hset("hash1", "subject","math");
    jedis.hset("hash1", "score","99");
    jedis.hset("hash1", "name","xiaoming");
    List result5 = jedis.hmget("hash1", "subject","score","name");
    System.out.println(result5);//[math, 99, xiaoming]
            
    //4.set
    jedis.sadd("set1", "math","math","english","chinese");
    jedis.sadd("set2", "math","chinese","art");
    jedis.sinterstore("set3", "set1","set2");
    System.out.println(jedis.smembers("set3"));//[math, chinese]
            
    //5.zset
    jedis.zadd("zset1", 100, "math");
    jedis.zadd("zset1", 200, "chinese");
    jedis.zadd("zset1", 300, "english");
    Set result6 = jedis.zrangeByScore("zset1", 100, 200);
    result6.forEach(string -> {
        System.out.print(string+" ");
    });//math chinese 
            
}catch(Exception e) {
    e.printStackTrace();
}finally {
    if(jedis != null) {
        jedis.close();
    }
}

四.客戶端操作

1.client list
列出與Redis服務(wù)器相連的所有客戶端信息。

屬性如下:

名稱 含義
id 客戶端的唯一標(biāo)識。自增,重啟后重置為0。
addr 客戶端連接的地址和端口。
fd socket的文件描述符。
name 客戶端的名稱。
age 當(dāng)前客戶端的連接時間。
idle 當(dāng)前客戶端的最近一次空閑時間。當(dāng)age等于idle表示連接一直處于空閑狀態(tài)。
flags 標(biāo)識當(dāng)前客戶端的類型。
db 當(dāng)前客戶端正在使用的數(shù)據(jù)庫索引下標(biāo)。
sub 當(dāng)前客戶端訂閱的頻道或者模式數(shù)。
psub 當(dāng)前客戶端訂閱的頻道或者模式數(shù)。
multi 當(dāng)前事務(wù)中已執(zhí)行命令個數(shù)。
qbuf 輸入緩沖區(qū)總?cè)萘俊?/td>
qbuf-free 輸入緩沖區(qū)的剩余容量。
obl 輸出緩沖區(qū)的固定緩沖區(qū)的大小。
oll 輸出緩沖區(qū)的動態(tài)緩沖區(qū)的大小。
omem 輸出緩沖區(qū)使用的字節(jié)數(shù)。
events 文件描述符事件。
cmd 當(dāng)前客戶端最后一次執(zhí)行的命令。

2.輸入緩沖區(qū)
作用:客戶端發(fā)送的命令不是直接發(fā)送給Redis服務(wù)器,而是先存放在輸入緩沖區(qū),Redis服務(wù)器從輸入緩沖區(qū)中獲得命令并執(zhí)行。

當(dāng)輸入緩沖區(qū)的輸入速度大于Redis服務(wù)器的處理速度且存在大量的bigkey或是Redis服務(wù)器發(fā)生阻塞,短期不能執(zhí)行命令時,都會造成輸入緩沖區(qū)過大,可以通過client list查看qbuf和qbuf-free的大小或是通過info clients命令找到最大的輸入緩沖區(qū)。

3.輸出緩沖區(qū)
作用:Redis服務(wù)器執(zhí)行命令后的結(jié)果不是直接返回給客戶端,而是先存放在輸出緩沖區(qū)。

輸出緩沖區(qū)分為固定緩沖區(qū)和動態(tài)緩沖區(qū),固定緩沖區(qū)是字節(jié)數(shù)組,動態(tài)緩沖區(qū)是列表,固定緩沖區(qū)使用完之后才會使用動態(tài)緩沖區(qū)。

通過client list和info clients可以監(jiān)控輸出緩沖區(qū)的異常情況。

4.客戶端的分類
(1)普通客戶端
(2)發(fā)布訂閱客戶端
(3)slave客戶端

5.客戶端操作

命令 含義
config set maxclients value 設(shè)置最大連接數(shù)
config get maxclients 設(shè)置最大連接數(shù)
info clients 查看當(dāng)前已經(jīng)連接的客戶端數(shù)量
config set timeout value 設(shè)置超時時間,空閑時間一旦大于超時時間,客戶端連接就會自動斷開。
client setName value 設(shè)置客戶端的名稱
client getName 獲得客戶端的名稱
client kill ip:port 關(guān)閉指定的ip:port的客戶端
client pause timeout (時間單位毫秒) 阻塞客戶端timeout毫秒

五.持久化
1.RDB
(1)概念:將當(dāng)前線程數(shù)據(jù)生成快照保存在磁盤中。

(2)方式
a.手動觸發(fā)
bgsave命令:Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,RDB的序列化由子進(jìn)程完成,在fork階段會出現(xiàn)堵塞。

b.自動觸發(fā)
在某些情況下自動觸發(fā)bgsave命令或是save命令。

(3)RDB的優(yōu)缺點(diǎn)
a.優(yōu)點(diǎn)
緊湊壓縮的二進(jìn)制文件,能夠代表Redis在某個時間點(diǎn)的數(shù)據(jù)備份,可復(fù)制到不同的機(jī)器進(jìn)行災(zāi)難恢復(fù)。Redis加載RDB恢復(fù)數(shù)據(jù)的速度快于AOF。

b.缺點(diǎn)
無法實(shí)現(xiàn)實(shí)時持久化,執(zhí)行fork操作創(chuàng)建子進(jìn)程是重量級操作,頻繁執(zhí)行成本較高,且老版本的Redis服務(wù)無法兼容新版本的RDB格式文件。

2.AOF
(1)概念:記錄每次的寫命令,重啟后執(zhí)行AOF文件中的命令以達(dá)到恢復(fù)數(shù)據(jù)的目的。可以用aof_enabled開啟aof功能。

(2)特點(diǎn):
a.AOF命令以文本協(xié)議格式的形式寫入內(nèi)容到aof_buf中,再由aof_buf同步到硬盤中。文本協(xié)議格式具有很好的兼容性以及避免了二次處理的開銷。而寫入到aof_buf中是為了避免直接寫入硬盤,以免硬盤的容量決定了追加寫入的性能。

b.aof重寫將無效的命令如del去掉,將多個命令合并成一個命令,以達(dá)到壓縮文件體積,加快Redis加載aof文件的速度。

六.復(fù)制
1.從節(jié)點(diǎn)和主節(jié)點(diǎn)之間建立關(guān)系有以下的方式:
(1)在配置文件(redis.conf)中加入slaveof {masterofhost} {masterofport}
(2)啟動redis-server時執(zhí)行:redis-server -slaveof {masterofhost} {masterofport}

2.主節(jié)點(diǎn)和從節(jié)點(diǎn)斷開和切換:
(1)斷開:slaveof no one
(2)切換:執(zhí)行命令slaveof {masterofhost} {masterofport}

3.復(fù)制的特點(diǎn)
(1)只能將主節(jié)點(diǎn)的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)。
(2)slaveof是異步命令,從節(jié)點(diǎn)保存了主節(jié)點(diǎn)的信息后返回,而不需要等到完全復(fù)制完畢才返回。
(3)可以通過命令info replication查看復(fù)制信息。
(4)從節(jié)點(diǎn)斷開與主節(jié)點(diǎn)的復(fù)制關(guān)系后,會晉升為主節(jié)點(diǎn)。
(5)從節(jié)點(diǎn)切換主節(jié)點(diǎn)之后,會刪除從節(jié)點(diǎn)當(dāng)前的所有數(shù)據(jù),對新節(jié)點(diǎn)數(shù)據(jù)進(jìn)行復(fù)制。

4.Redis的復(fù)制關(guān)系
(1)一主一從:用于主節(jié)點(diǎn)宕機(jī)時,從節(jié)點(diǎn)提供故障轉(zhuǎn)移支持。
(2)一主多從:用于讀寫分離,主節(jié)點(diǎn)執(zhí)行寫命令,從節(jié)點(diǎn)執(zhí)行讀命令,當(dāng)高并發(fā)寫時,將寫命令的數(shù)據(jù)復(fù)制到從節(jié)點(diǎn)就需要消耗比較多的網(wǎng)絡(luò)帶寬。
(3)樹狀主從:從節(jié)點(diǎn)不僅可以復(fù)制主節(jié)點(diǎn)的數(shù)據(jù),還可以作為其他從節(jié)點(diǎn)的主節(jié)點(diǎn)進(jìn)行向下復(fù)制??梢杂行Ы档椭鞴?jié)點(diǎn)的負(fù)載和傳輸給從節(jié)點(diǎn)的數(shù)據(jù)量。

5.全量復(fù)制和部分復(fù)制
全量復(fù)制:將主節(jié)點(diǎn)的數(shù)據(jù)一次性發(fā)生給從節(jié)點(diǎn)。一般用于初次復(fù)制場景。
部分復(fù)制:僅復(fù)制主節(jié)點(diǎn)的部分?jǐn)?shù)據(jù)給從節(jié)點(diǎn)。一般用于處理主從復(fù)制中網(wǎng)絡(luò)閃斷等原因造成的數(shù)據(jù)丟失場景。
從節(jié)點(diǎn)執(zhí)行命令:psync {runId} {offse7dxzt}
runId是主節(jié)點(diǎn)的運(yùn)行id,offset是從節(jié)點(diǎn)已復(fù)制的偏移量。主節(jié)點(diǎn)響應(yīng)寫命令時,會把寫命令發(fā)送給從節(jié)點(diǎn),還會將寫命令寫入復(fù)制積壓緩沖區(qū)。

七.Redis的阻塞
利用日志對Redis的異常進(jìn)行監(jiān)控。
內(nèi)部原因:不合理使用API或數(shù)據(jù)結(jié)構(gòu)(可能由此導(dǎo)致慢查詢等)、CPU飽和(Redis是單線程,只會使用單個CPU)、持久化阻塞(fork操作產(chǎn)生阻塞,AOF對硬盤的操作產(chǎn)生阻塞或HugePage寫操作阻塞)等。
外在原因:CPU競爭、內(nèi)存交換、網(wǎng)絡(luò)問題等。

八.Redis的內(nèi)存
1.Redis進(jìn)程內(nèi)存消耗

可以通過config set maxmemory value設(shè)置最大內(nèi)存以達(dá)到伸縮內(nèi)存的目的

2.Redis內(nèi)存的回收
(1)刪除已過期的鍵對象。包括惰性刪除(查詢時判斷鍵對象是否過期,如果過期執(zhí)行刪除操作并返回空)和定時刪除。
(2)內(nèi)存達(dá)到maxmemory時執(zhí)行內(nèi)存溢出控制策略。內(nèi)存溢出策略包括noeviction,volatile-lru,allkeys-lru,allkeys-random,volatile-random和volatile-ttl,可以通過config set maxmemory-policy {policy}動態(tài)設(shè)置。

3.內(nèi)存優(yōu)化
(1)縮短鍵和值得長度,使用高效二進(jìn)制序列化工具。
(2)使用對象共享池優(yōu)化小整數(shù)對象。
(3)避免字符串的追加操作,因?yàn)樽址芳訒?dǎo)致內(nèi)存的預(yù)分配,降低內(nèi)存的分配次數(shù)。
(4)ziplist壓縮編碼的原則是追求時間和空間的平衡,hash,zset,list的內(nèi)部編碼可以是ziplist,可以通過{type}-max-ziplist-value和{type}-max-ziplist-entries進(jìn)行編碼的控制。
(5)intset是set的內(nèi)部編碼,整數(shù)集合盡量使用intset編碼,
(6)數(shù)據(jù)優(yōu)先使用整數(shù),比字符串類型更節(jié)省內(nèi)存。

九.Redis Sentinel(哨兵)

1.Redis Sentinel是什么?
一個分布式架構(gòu),包括Sentinel節(jié)點(diǎn),Redis數(shù)據(jù)節(jié)點(diǎn)和分布在多個物理機(jī)的客戶端應(yīng)用。完成主節(jié)點(diǎn)不可用時的故障轉(zhuǎn)移處理工作,提供了高可用的解決方案。

2.Sentinel節(jié)點(diǎn)發(fā)現(xiàn)故障轉(zhuǎn)移前的內(nèi)容:
(1)每個Sentinel節(jié)點(diǎn)會對所有的數(shù)據(jù)節(jié)點(diǎn)(包括主節(jié)點(diǎn)和從節(jié)點(diǎn))和其他的Sentinel節(jié)點(diǎn)進(jìn)行監(jiān)控。
(2)當(dāng)半數(shù)以上的節(jié)點(diǎn)認(rèn)為主節(jié)點(diǎn)故障不可用,就會選擇其中一個Sentinel節(jié)點(diǎn)作為領(lǐng)導(dǎo)者進(jìn)行故障轉(zhuǎn)移處理。

3.故障轉(zhuǎn)移處理的步驟如下:
(1)對某一個從節(jié)點(diǎn)執(zhí)行slaveof no one,晉升為主節(jié)點(diǎn)。
(2)其他的從節(jié)點(diǎn)復(fù)制新的主節(jié)點(diǎn)命令(slaveof new master)。
(3)舊的主節(jié)點(diǎn)恢復(fù)后也要復(fù)制新的主節(jié)點(diǎn)命令(slaveof new master)。
(4)通知應(yīng)用方新的主節(jié)點(diǎn)。

4.為什么需要多個Rentinel節(jié)點(diǎn)?
由多個Rentinel節(jié)點(diǎn)對主節(jié)點(diǎn)不可達(dá)進(jìn)行判斷,可以防止誤判。如果有個別Rentinel節(jié)點(diǎn)失效,整個Rentinel集合依然可用。

5.Redis Sentinel的搭建
(1)建立配置文件,逐一開啟。(配置文件的寫法可以去看《Redis開發(fā)與設(shè)計(jì)》第九章)
開啟主節(jié)點(diǎn):redis-server redis-6379.conf
開啟從節(jié)點(diǎn) redis-server redis-6380.conf

       redis-server redis-6381.conf

開啟sentinel節(jié)點(diǎn) redis-server redis-sentinel-26379.conf --sentinel

             redis-server redis-sentinel-26380.conf --sentinel
             redis-server redis-sentinel-26381.conf --sentinel

查看主節(jié)點(diǎn)的從節(jié)點(diǎn):redis-cli -h 127.0.0.1 -p 6379 info replication
查看從節(jié)點(diǎn)的主節(jié)點(diǎn) redis-cli -h 127.0.0.1 -p 6380 info replication
查看sentinel節(jié)點(diǎn)監(jiān)控的主節(jié)點(diǎn) redis-cli -h 127.0.0.1 -p 26379 info sentinel

(2)sentinel配置文件的一些參數(shù)

  • 
    
    <
    
    參數(shù) 含義
    sentinel monitor sentinel節(jié)點(diǎn)要監(jiān)控名字叫,ip地址是,端口地址是的主節(jié)點(diǎn)。表示判定主節(jié)點(diǎn)不可達(dá)需要的票數(shù)。
    sentinel down-after-milliseconds sentinel節(jié)點(diǎn)會向數(shù)據(jù)節(jié)點(diǎn)和其他sentinel節(jié)點(diǎn)發(fā)送ping命令,如果節(jié)點(diǎn)在毫秒時間內(nèi)沒有回復(fù),則認(rèn)為節(jié)點(diǎn)不可達(dá)。
    sentinel parallel-syncs 一次故障轉(zhuǎn)移后,每次向新節(jié)點(diǎn)發(fā)起復(fù)制操作的從節(jié)點(diǎn)個數(shù)。
    sentinel failover-timeout 故障轉(zhuǎn)移的超時時間。
    sentinel authpass 添加主節(jié)點(diǎn)的密碼。
    sentinel notification-script
    閱讀需要支付1元查看