久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis使用規(guī)范和監(jiān)控方法是什么

188次閱讀
沒有評論

共計 5551 個字符,預(yù)計需要花費 14 分鐘才能閱讀完成。

這篇文章主要講解了“Redis 使用規(guī)范和監(jiān)控方法是什么”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Redis 使用規(guī)范和監(jiān)控方法是什么”吧!

一、前言

在互聯(lián)網(wǎng)應(yīng)用中,緩存成為高并發(fā)架構(gòu)的關(guān)鍵組件。本文主要介紹緩存使用的典型場景、實操案例分析、Redis 使用規(guī)范及常規(guī) Redis 監(jiān)控。

二、常見緩存對比

常見的緩存方案:本地緩存包括 HashMap/ConcurrentHashMap、Ehcache、Memcache、Guava Cache 等,緩存中間件包括 Redis、Tair 等。

三、Redis 使用場景

1、計數(shù)

Redis 實現(xiàn)快速計數(shù)及緩存功能。

例如:視頻或直播在線觀看人數(shù),用戶每播放一次,就會自增 1。

2、Session 集中管理

Session 可以存儲在應(yīng)用服務(wù)是 JVM 中,但這一種方案會有一致性的問題,還有高并發(fā)下,會引發(fā) JVM 內(nèi)存溢出。Redis 將用戶的 Session 集中管理,這種情況下只要保證 Redis 的高可用和擴展性,每次用戶更新或查詢登錄都直接從 Redis 中信息獲取。

3、限速

例如:高并發(fā)的秒殺活動,使用 incrby 命令實現(xiàn)原子性遞增。

例如:業(yè)務(wù)要求用戶一分鐘內(nèi),只能獲取 5 次驗證碼。

4、排行榜

關(guān)系型數(shù)據(jù)庫在排行榜方面查詢速度普遍偏慢,所以可以借助 redis 的 SortedSet 進行熱點數(shù)據(jù)的排序。

比如在項目中,如果需要統(tǒng)計主播的吸金排行榜,可以以主播的 id 作為 member, 當(dāng)天打賞的活動禮物對應(yīng)的熱度值作為 score, 通過 zrangebyscore 就可以獲取主播活動日榜。

5、分布式鎖

在實際的多進程并發(fā)場景下,使用分布式鎖來限制程序的并發(fā)執(zhí)行。多用于防止高并發(fā)場景下,緩存被擊穿的可能。

分布式鎖的實際就是 占坑,當(dāng)另一個進程來執(zhí)行 setnx 時,發(fā)現(xiàn)標(biāo)識位已經(jīng)為 1,只好放棄或者等待。

四、案例解析

1、過期設(shè)置 - set 命令會去掉過期時間

Redis 所有的數(shù)據(jù)結(jié)構(gòu),都可以設(shè)置過期時間。如果一個字符串已經(jīng)設(shè)置了過期時間,然后重新設(shè)置它,會導(dǎo)致過期時間消失。所以在項目中需要合理評估 Redis 容量,避免因為頻繁 set 導(dǎo)致沒有過期策略,間接導(dǎo)致內(nèi)存被占滿。

如下是 Redis 源碼截圖:

2、Jedis 2.9.0 及以下版本過期設(shè)置 BUG

發(fā)現(xiàn) Jedis 在進行 expiredAt 命令調(diào)用時有 bug,最終調(diào)用的是 pexpire 命令,這個 bug 會導(dǎo)致 key 過期時間很長,導(dǎo)致 Redis 內(nèi)存溢出等問題。建議升級到 Jedis 2.9.1 及以上版本。

BinaryJedisCluster.java 源碼如下:

@Override public Long pexpireAt(final byte[] key, final long millisecondsTimestamp) { return new JedisClusterCommand Long (connectionHandler, maxAttempts) { @Override public Long execute(Jedis connection) { return connection.pexpire(key, millisecondsTimestamp); // 此處 pexpire 應(yīng)該是 pexpireAt } }.runBinary(key); }

對比 pexpire 和 pexpireAt:

比如我們當(dāng)前使用的時間是 2018-06-14 17:00:00,它的 unix 時間戳為 1528966800000 毫秒,當(dāng)我們使用 PEXPIREAT 命令時,由于是過去的時間,相應(yīng)的 key 會立即過期。

而我們誤用了 PEXPIRE 命令時,key 不會立即過期,而是等到 1528966800000 毫秒后才過期,key 過期時間會相當(dāng)長,約幾 W 天后,從而可能導(dǎo)致 Redis 內(nèi)存溢出、服務(wù)器崩潰等問題。

3、緩存被擊穿

緩存的 key 有過期策略,如果恰好在這個時間點對這個 Key 有大量的并發(fā)請求,這些請求發(fā)現(xiàn)緩存過期一般都會從后端 DB 回源數(shù)據(jù)并回設(shè)到緩存,這個時候大并發(fā)的請求可能會瞬間把后端 DB 壓掛。

業(yè)界常用優(yōu)化方案有兩種:

  第一種:使用分布式鎖,保證高并發(fā)下,僅有一個線程能回源后端 DB;

  第二種:保證高并發(fā)的請求到的 Redis key 始終是有效的,使用非用戶請求回源后端,改成主動回源。一般可以使用異步任務(wù)進行緩存的主動刷新。

4、Redis-standalone 架構(gòu)禁止使用非 0 庫

Redis 執(zhí)行命令 select 0 和 select 1 切換,造成性能損耗。

RedisTemplate 在執(zhí)行 execute 方法的時候會先獲取鏈接。

執(zhí)行到 RedisConnectionUtils.java,會有一段獲取鏈接的方法。

JedisConnectionFactory.java 會調(diào)用

JedisConnection 構(gòu)造器,注意這邊的 dbIndex 就是數(shù)據(jù)庫編號,如:1

繼續(xù)跟進 JedisConnection 代碼,當(dāng)選擇庫大于 1 時,會有 select db 操作。如果一直使用 0 庫是不需要額外執(zhí)行切庫命令的。知道了第一個切庫 select 1 的地方,那么 select 0 是哪來的呢?

其實客戶端使用 Redis 也會是要釋放鏈接的,只不過 RedisTemplate 已經(jīng)幫我們自動釋放了,讓我們再回到一開始 RedisTemplate 執(zhí)行 execute(…) 方法的地方。

下面還是 RedisConnectionUtils.java,執(zhí)行鏈接關(guān)閉的代碼。

按代碼注釋的意思,如果選擇庫編號不為 0,spring-data-redis 框架每次都會執(zhí)行重置 select 0!

筆者在 vivo 商城業(yè)務(wù)中,商品詳情頁接口經(jīng)過上面的調(diào)優(yōu),性能提高了 3 倍多。

進一步驗證數(shù)據(jù)庫切換至少影響性能 3 倍左右(視具體業(yè)務(wù)而定)。

Rediscluster 集群數(shù)據(jù)庫,默認 0 庫,無法選擇其他數(shù)據(jù)庫,也就避免了這個問題。

5、當(dāng)心時間復(fù)雜度 o(n)Redis 命令

Redis 是單線程的,所以線程安全的。

Redis 使用非阻塞 IO,并且大部分命令的時間復(fù)雜度 O(1)。

使用高耗時的命令是非常危險的,會占用唯一的一個線程的大量處理時間,導(dǎo)致所有的請求都被拖慢。

例如:獲取所有 set 集合中的元素 smembers myset,返回指定 Hash 中所有的 member,時間復(fù)雜度 O(N)。

緩存的 Value 集合變大,當(dāng)高并接口請求時,會從 Redis 讀取相關(guān)數(shù)據(jù),每個請求讀取的時間變長,不斷的疊加,導(dǎo)致出現(xiàn)熱點 KEY 情況,Redis 某個分片處于阻塞,CPU 使用率達到 100%。

6、緩存熱 key

在 Redis 中,訪問頻率高的 key 稱為熱點 key,當(dāng)某一熱點 key 的請求到 Server 主機時,由于請求量特別大,導(dǎo)致主機資源不足,甚至宕機,影響正常的服務(wù)。

熱 key 問題的產(chǎn)生,有如下兩種原因:

  用戶消費的數(shù)據(jù)遠大于生產(chǎn)的數(shù)據(jù),比如熱賣商品或秒殺商品、熱點新聞、熱點評論等,這些典型的讀多寫少的場景會產(chǎn)生熱點問題;

  請求分片集中,超過單 Server 的性能極限,比如 固定名稱 key,哈希落入一臺 Server,訪問量極大的情況,超過 Server 極限時,就會導(dǎo)致熱點 Key 問題的產(chǎn)生。

那么在實際業(yè)務(wù)中,如何識別到熱點 key 呢?

  憑借業(yè)務(wù)經(jīng)驗,進行預(yù)估哪些是熱 key;

  客戶端統(tǒng)計收集,本地統(tǒng)計或者上報;

  如果服務(wù)端有代理層,可以在代理層進行收集上報。

當(dāng)我們識別到熱 key,如何解決熱 key 問題?

 Redis 集群擴容:增加分片副本,均衡讀流量;

  進一步對熱 key 進行散列,比如將一個 key 備份為 key1,key2 hellip; hellip;keyN,同樣的數(shù)據(jù) N 個備份,N 個備份分布到不同分片,訪問時可隨機訪問 N 個備份中的一個,進一步分擔(dān)讀流量;

  使用二級緩存,即本地緩存。

當(dāng)發(fā)現(xiàn)熱 key 后,將熱 key 對應(yīng)數(shù)據(jù)首先加載到應(yīng)用服務(wù)器本地緩存中,減少對 Redis 的讀請求。

五、Redis 規(guī)范

1、禁止使用非 database 0

說明:

Redis-standalone 架構(gòu),禁止使用 Redis 中的其他 database。

原由:

  為以后業(yè)務(wù)遷移 Redis Cluster 保持兼容性;

  多個 database 用 select 切換時,更消耗 CPU 資源;

  更易自動化運維管理,如 scan/dbsize 命令只用于當(dāng) database;

  部分 Redis Clients 因線程安全問題,不支持單實例多 database。

2、Key 設(shè)計規(guī)范

按業(yè)務(wù)功能命名 key 前綴,防止 key 沖突覆蓋,推薦 用冒號分隔,例如,業(yè)務(wù)名: 表名:id:,如 live:rank:user:weekly:1:202003。

Key 的長度小于 30 個字符,Key 名字本身是 String 對象,Redis 硬編碼限制最大長度 512MB。

在 Redis 緩存場景,推薦 Key 都設(shè)置 TTL 值,保證不使用的 Key 能被及時清理或淘汰。

Key 設(shè)計時禁止包含特殊字符,如空格、換行、單雙引號以及其他轉(zhuǎn)義字符。

3、Value 設(shè)計規(guī)范

單個 Value 大小必須控制 10KB 以內(nèi),單實例鍵個數(shù)過大,可能導(dǎo)致過期鍵的回收不及時。

set、hash、list 等復(fù)雜數(shù)據(jù)類型,要盡量降低數(shù)據(jù)結(jié)構(gòu)中的元素個數(shù),建議個數(shù)不要超過 1000。

4、關(guān)注命令時間復(fù)雜度

推薦使用 O(1) 命令,如 get scard 等。

O(N) 命令關(guān)注 N 的數(shù)量,如下命令需要對 N 值在業(yè)務(wù)層面做控制。

 hgetall

 lrange

 smembers

 zrange

例如:smember 命令時間復(fù)雜度為 O(n),當(dāng) n 持續(xù)增加時,會導(dǎo)致 Redis CPU 持續(xù)飆高,阻塞其他命令的執(zhí)行。

5、Pipeline 使用

說明:Pipeline 是 Redis 批量提交的一種方式, 也就是把多個命令操作建立一次連接發(fā)給 Redis 去執(zhí)行, 會比循環(huán)的單次提交性能更優(yōu)。

Redis 客戶端執(zhí)行一條命令分 4 個過程:發(fā)送命令 – 命令排隊 – 命令執(zhí)行 – 返回結(jié)果。

Redis 使用規(guī)范和監(jiān)控方法是什么

常用的 mget、mset 命令,有效節(jié)約 RTT(命令執(zhí)行往返時間),但 hgetall 并沒有 mhgetall,是不支持批量操作的。此時,需要使用 Pipeline 命令

Redis 使用規(guī)范和監(jiān)控方法是什么

例如:直播中臺項目中,需要同時查詢主播日、周、月排行榜,使用 PIPELINE 一次提交多個命令,同時返回三個榜單數(shù)據(jù)。

6、線上禁用命令

  禁止使用 Monitor

  禁止生產(chǎn)環(huán)境使用 monitor 命令,monitor 命令在高并發(fā)條件下,會存在內(nèi)存暴增和影響 Redis 性能的隱患

  禁止使用 Keys

  keys 操作是遍歷所有的 key,如果 key 非常多的情況下導(dǎo)致慢查詢,會阻塞其他命令。所以禁止使用 keys 及 keys pattern 命令。

  建議線上使用 scan 命令代替 keys 命令。

  禁止使用 Flushall、Flushdb

          刪除 Redis 中所有數(shù)據(jù)庫中的所有記錄,并且該命令是原子性的,不會終止執(zhí)行,一旦執(zhí)行,將不會執(zhí)行失敗。

  禁止使用 Save

        阻塞當(dāng)前 redis 服務(wù)器,直到持久化操作完成為止,對于內(nèi)存較大的實例會造成長時間的阻塞

 BGREWRITEAOF

        手動 AOF,手動持久化對于內(nèi)存較大的實例會造成長時間的阻塞

 Config

        Config 是客戶端配置方式,不利于 Redis 運維。建議在 Redis 配置文件中設(shè)置。

六、Redis 監(jiān)控

1、慢查詢

方法一:slowlog 獲取慢查詢?nèi)罩?

127.0.0.1:{port}  slowlog get 5 1) 1) (integer) 47 2) (integer) 1533810300 3) (integer) 175833 4) 1)  DEL  2)  spring:session:expirations:1533810300000  2) 1) (integer) 46 2) (integer) 1533810300 3) (integer) 117400 4) 1)  SMEMBERS

方法二:更全面的慢查詢可以通過 CacheCloud 工具監(jiān)控。

路徑:應(yīng)用列表 - 點擊相關(guān)應(yīng)用名 - 點擊 慢查詢 Tab 頁。

點擊 慢查詢,重點關(guān)注慢查詢個數(shù)及相關(guān)命令。

2、監(jiān)控 Redis 實例綁定的 CPU 核心使用率

由于 Redis 是單線程,重點監(jiān)控 Redis 實例綁定的 CPU 核心使用率。

一般 CPU 資源使用率為 10% 左右,如果使用率高于 20% 時,考慮是否使用了 RDB 持久化。

3、Redis 分片負載均衡

當(dāng)前 redis-cluster 架構(gòu)模式,3 個 master 和 3 個 Slave 組成的集群,關(guān)注 Redis-cluster 每個分片 requests 流量均衡情況;

通過命令獲?。?/p>

redis-cli -p{port} -h{host} --stat

一般情況,超過 12W 需要告警。

4、關(guān)注大 key BigKey

通過 Redis 提供的工具,redis-cli 定時掃描相應(yīng) Redis 大 Key,進行優(yōu)化。

具體命令如下:

redis-cli -h 127.0.0.1 -p {port} --bigkeys

redis-memory-for-key -s {IP} -p {port} XXX_KEY

一般超過 10K 為大 key,需要重點關(guān)注,建議從業(yè)務(wù)層面優(yōu)化。

5、監(jiān)控 Redis 占用內(nèi)存大小

Info memory 命令查看,避免在高并發(fā)場景下,由于分配的 MaxMemory 被耗盡,帶來的性能問題。

重點關(guān)注 used_memory_human 配置項對應(yīng)的 value 值,增量過高時,需要重點評估。

感謝各位的閱讀,以上就是“Redis 使用規(guī)范和監(jiān)控方法是什么”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對 Redis 使用規(guī)范和監(jiān)控方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-27發(fā)表,共計5551字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 沂源县| 浪卡子县| 寿阳县| 潞城市| 虹口区| 淮安市| 嘉义县| 措勤县| 武功县| 大足县| 丽水市| 喀什市| 乳山市| 青海省| 驻马店市| 丰台区| 嘉禾县| 阿拉善左旗| 奉化市| 麟游县| 环江| 河间市| 五常市| 吴江市| 花垣县| 大关县| 张掖市| 岐山县| 邵阳市| 汝南县| 南丰县| 苍山县| 公主岭市| 常州市| 丁青县| 台前县| 通辽市| 延边| 崇仁县| 正宁县| 资溪县|