Redis面試文章觀後,持續更新知識中

https://zhuanlan.zhihu.com/p/32540678?utm_source=wechat_session&utm_medium=social&from=singlemessage

Geo比較簡單,直接看api即可

布隆過濾器仔細看了一遍

主要是這4方面 即BloomFilter的以下參數:

  • m 位數組的長度
  • n 加入其中元素的數量
  • k 哈希函數的個數
  • f False Positive  可以理解爲誤識別率

但是Redis String最大量爲512M,最大值爲,如果超過超過這個量了怎麼辦呢,分散計算,通過bitmap的進行hash分塊。

https://redis.io/topics/data-types-intro

布隆過濾器Java實現https://github.com/MagnusS/Java-BloomFilter

布隆過濾器Redis實現https://github.com/olylakers/RedisBloomFilter

Redis在實現字典時用到了兩種不同的哈希算法,MurmurHash便是其中一種(另一種是djb)

優點:規律性較強的key,MurmurHash的隨機分佈特徵表現更良好

適用範圍:是一種非加密哈希函數,適用於一般的哈希檢索操作。

Redis與數據庫事務的區別

Redis的事務是這樣的

multi
命令1
命令2
命令3
exec

如果命令2失敗,仍然會提交,也就是發現命令執行出現問題了,不能自動回滾,而要手動通過程序回滾。

還有一點關於watch,watch可以對3個命令的key進行監控,如果key的value改變,那麼此次事務失敗,對key的監控取消。

keys指令與scan指令的區別

keys指令是阻塞指令,可能服務卡頓, 結果準確

scan指令是無阻塞指令,不影響服務使用,結果不準確,可能有重複。

Redis 發佈訂閱 與MQ的局別

1.Redis的發佈訂閱無法消費離線的數據,而MQ通過消息持久化是可以的。

2.Redis沒有ack的功能

關於Redis的隊列

rpush生產消息,lpop消費消息。

lpush生產消息,rpop消費消息。

redis list源碼 http://zhangtielei.com/posts/blog-redis-quicklist.html

Redis優先級隊列實現

可以通過兩種方式來實現,List或者Sorted Set。

List方式適用於優先級類型比較有限的情況,就是用窮舉法生產多個優先級List,然後從高到低循環取List的數據。

Sorted Set方式對於優先級類型沒有限制,多少均可,但是性能呢,感覺要稍差一些了,代碼如下,稍後給出性能測試,

		Jedis jedis = pool.getResource();		
		System.out.println("begin");
		try {
			Pipeline  pl=jedis.pipelined();
			String key="Priority";
			pl.del(key);
			for(int i=0;i<10;i++){
				pl.zadd(key, 0.1d, "member"+i);
			}
			for(int i=10;i<20;i++){
				pl.zadd(key, i+0.1d, "member"+i);
			}
			Response<Set<String>> res=pl.zrevrange(key, 0, 0);
			pl.sync();
			Set<String> result=res.get();
			String member=null;
			if(!result.isEmpty()){
				Iterator it=result.iterator();
				member=it.next().toString();
			}
			System.out.println(member);
			pl.zrem(key, member);
			pl.sync();
			System.out.println("end");
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			if(jedis!=null){
				pool.returnResource(jedis);
			}
			
		}

menber爲10個字符 10萬級別 14毫秒

                               100萬級別  76毫秒

                              1000萬級別 我的客戶端掛了...

redis鎖與zk鎖對比 http://blog.csdn.net/pzqingchong/article/details/52516602 


運維如何進行慢查詢排查

檢查慢查詢配置

config get slowlog-log-slower-than
config get slowlog-max-len


config set slowlog-log-slower-than 1000  (單位毫秒,1000毫秒即1微秒,)

config set slowlog-max-len 256

config rewrite

查詢慢查詢列表長度

slowlog len

查看慢查詢日誌

slowlog get

redis4版本的日誌有變化,3.x的版本中有4個字段  標識id、發生時間戳、命令耗時、執行命令和參數;4中加入了client的ip和端口、客戶端名稱。詳見https://redis.io/commands/slowlog

tcp-backlog:TCP三次握手後,會將接受的連接放入隊列中,tcpbacklog
就是隊列的大小,它在Redis中的默認值是511。如果/proc/sys/net/core/somaxconn小於tcp-backlog,那麼在Redis啓動時會
看到如下日誌,並建議將/proc/sys/net/core/somaxconn設置更大

echo 511 > /proc/sys/net/core/somaxconn


config set client-output-buffer-limit "normal 1048576 1048576 60 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

找到omem非零的客戶端連接:

redis-cli client list | grep -v "omem=0"
./redis-cli -h 192.168.112.133 -p 6379  client list | grep -v "omem=0"

RDB

SAVE 阻塞當前Redis服務器,線上環境不建議使用。

BGSAVE Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。

執行lastsave命令可以獲取最後一次生成RDB的時間,對應info統計的rdb_last_save_time選項。

需要設置sysctl vm.overcommit_memory=1允許內核可以分配所有的物理內存,防止Redis進程執行fork時因系統剩餘內存不足而失敗。

Redis的內存上限可以通過config set maxmemory進行動態修改共享對象池與maxmemory+LRU策略衝突,使用時需要注意。對於ziplist編碼的值對象,即使內部數據爲整數也無法使用共享對象池,因爲ziplist使用壓縮且內存連續的結構,對象共享判斷成本過高,ziplist編碼細節後面內容詳細說明。

低一致性業務建議配置最大內存和淘汰策略的方式使用。
高一致性業務可以結合使用超時剔除和主動更新,這樣即使主動更新

出了問題,也能保證數據過期時間後刪除髒數據。

bigkey問題

Redis將在4.0版本支持lazy delete free的模式,

UNLINK命令,此命令是一個非阻塞命令。

Redis過期數據刪除策略

定期刪除爲主動刪除:Redis會定期主動淘汰一批已過去的key
惰性刪除爲被動刪除:用到的時候纔會去檢驗key是不是已過期,過期就刪除

惰性刪除爲redis服務器內置策略,key過期的時候不刪除,每次從數據庫獲取key的時候去檢查是否過期,若過期,則刪除,返回null。

定期刪除可以通過:
第一、配置redis.conf 的hz選項,默認爲10 (即1秒執行10次,100ms一次,值越大說明刷新頻率越快,最Redis性能損耗也越大) 
第二、配置redis.conf的maxmemory最大值,當已用內存超過maxmemory限定時,就會觸發主動清理策略

自己碰到的redis 主從同步失效的問題


原有情況是節前啓動了3個redis節點,1個master2個slave節點,3個Sentinel node,節後發現

1.master原來ip爲15變成了slave節點,而且狀態是down的狀態

2.使用slave of none和slave of 16後命令提示已經連接到ip爲16的節點上,但是執行sync提示同步失敗

3.在16上執行client list命令找不到15的client

4.15節點執行ping有迴應

5.16節點新增加的數據在15上沒有,而17節點上存在。

本來想查log日誌,發現居然沒有配置.....在心裏重新過一遍複製的過程

1.保存主節點(master)信息。
2.與主節點建立網絡連接
3.發送ping命令
4.權限驗證
5.同步數據集

6.命令持續複製

因此懷疑是權限的問題,執行 config get masterauth發現爲空,執行config set masterauth 密碼,成功,提示連接成功。

在16上執行client list命令看到新出現了一個15的client。

優化配置

vm.swappiness   操作系統使用swap區的傾向程度,默認爲60,建議修改爲1,0在linux3.5以上的版本意味着OOM KILLER也不使用swap區。


查看redis的swap區情況

redis-cli -h 10.1.8.15 -p 6379 info server | grep process_id

cat /proc/27372/smaps


關閉THP

Transparent Huge Pages(THP)大頁內存

cat /sys/kernel/mm/transparent_hugepage/defrag
echo never > /sys/kernel/mm/transparent_hugepage/enabled
grep -i HugePages_Total /proc/meminfo
cat /proc/sys/vm/nr_hugepages 


查看鏈接

OOM killer

/proc/{progress_id}/oom_score
/proc/{progress_id}/oom_adj
echo {value} > /proc/${process_id}/oom_adj
cat /proc/{progress_id}/oom_score_adj

oom_adj介於 [-17,15]之間,越高的權重,意味着更可能被oom killer選中,-17表示禁止被kill掉。redis的默認爲0,建議改小到-15,另外我發現,oom_adj的值只能爲奇數。


TCP backlog

cat /proc/sys/net/core/somaxconn

echo 511 > /proc/sys/net/core/somaxconn


建議調大linux的值,大於等於redis對應的tcp backlog的值。


https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651747704&idx=3&sn=cd76ad912729a125fd56710cb42792ba&chksm=bd12ac358a6525235f51e3937d99ea113ed45542c51bc58bb9588fa1198f34d95b7d13ae1ae2&mpshare=1&scene=23&srcid=03165gAv4AjKuRGn3FToo69J#rd

使用命令taskset可以爲進程設置CPU親緣性,操作十分簡單,一句taskset -cp cpu-list pid即可完成綁定。經過一番壓測,我們發現使用8個core處理中斷時,流量直至打滿雙萬兆網卡也不會出現丟包,因此決定將中斷的親緣性設置爲物理機上前8個core,Redis進程的親緣性設置爲剩下的所有core。

未完待續

Lua語言

boolean numbers strings tables




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章