Redis(二):Redis高級特性和應用(慢查詢、Pipeline、事務)

Redis的慢查詢

許多存儲系統(例如 MySQL)提供慢查詢日志幫助開發和運維人員定位系統存在的慢操作。所謂慢查詢日志就是系統在命令執行前后計算每條命令的執行時間,當超過預設閥值,就將這條命令的相關信息(例如:發生時間,耗時,命令的詳細信息)記錄下來,Redis也提供了類似的功能。

Redis客戶端執行一條命令分為如下4個部分:

  • 發送命令
  • 命令排隊
  • 執行命令
  • 返回結果

需要注意,慢查詢只統計步驟3的時間,所以沒有慢查詢并不代表客戶端沒有超時問題。因為有可能是命令的網絡問題或者是命令在Redis在排隊,所以不是說命令執行很慢就說是慢查詢,而有可能是網絡的問題或者是Redis服務非常繁忙(隊列等待長)。

慢查詢配置

1、動態設置

慢查詢的閾值默認值是10毫秒。
參數:slowlog-log-slower-than就是時間預設閥值,它的單位是微秒(1秒=1000毫秒=1 000 000微秒),默認值是10 000,假如執行了一條“很慢”的命令(例如keys *),如果它的執行時間超過了10 000微秒,也就是10毫秒,那么它將被記錄在慢查詢日志中。
查看slowlog-log-slower-than

config get slowlog-log-slower-than

更新slowlog-log-slower-than

config set slowlog-log-slower-than 20000 

使用config set完后,若想將配置持久化保存到Redis.conf,要執行config rewrite

config rewrite

查看慢查詢

 #設置慢查詢時間閾值為10微秒config set slowlog-log-slower-than 10#查看所有的keykeys *#查看慢查詢個數slowlog len#展示慢查詢信息(查詢2個慢查詢)slowlog get 2


慢查詢日志重置

slowlog reset

Pipeline

前面慢查詢的時候提到過時間消耗,其中1(發送命令)4(返回結果)花費的時間稱為Round Trip Time (RTT,往返時間),也就是數據在網絡上傳輸的時間。

Redis提供了批量操作命令(例如mget、mset等),有效地節約RTT。

但大部分命令是不支持批量操作的,例如要執行n次 hgetall命令,并沒有mhgetall命令存在,需要消耗n次RTT。

#設置一個hash對象json
hset json a 1 b 2#獲取json的屬性a
hget json a
#湖區json的屬性b
hget json b#一次性獲取json對象
hgetall json

舉例:Redis的客戶端和服務端可能部署在不同的機器上。例如客戶端在本地(上海),Redis服務器在阿里云的北京,兩地直線距離約為1200公里,那么1次RTT時間=1200 x2/ ( 300000×2/3 ) =12毫秒,(光在真空中傳輸速度為每秒30萬公里,這里假設光纖為光速的2/3 )。而Redis命令真正執行的時間通常在微秒(1000微妙=1毫秒)級別,所以才會有Redis 性能瓶頸是網絡這樣的說法。

Pipeline(流水線)機制能改善上面這類問題,它能將一組 Redis命令進行組裝,通過一次RTT傳輸給Redis,再將這組Redis命令的執行結果按順序返回給客戶端,沒有使用Pipeline執行了n條命令,整個過程需要n次RTT。

使用Pipeline 執行了n次命令,整個過程需要1次RTT。

 public void plSet(List<String> keys,List<String> values) {Jedis jedis = null;try {jedis = jedisPool.getResource();Pipeline pipelined = jedis.pipelined();for(int i=0;i<keys.size();i++){pipelined.set(keys.get(i),values.get(i));}pipelined.sync();} catch (Exception e) {throw new RuntimeException("執行Pipeline設值失敗!",e);} finally {jedis.close();}}/**逐個set和利用pipeline的處理時間對比*/public void testPipeline() {long setStart = System.currentTimeMillis();for (int i = 0; i < TEST_COUNT; i++) { //單個的操作redisString.set("testStringM:key_" + i, String.valueOf(i));}long setEnd = System.currentTimeMillis();System.out.println("非pipeline操作"+TEST_COUNT+"次字符串數據類型set寫入,耗時:" + (setEnd - setStart) + "毫秒");List<String> keys = new ArrayList<>(TEST_COUNT);List<String> values= new ArrayList<>(TEST_COUNT);for (int i = 0; i < keys.size(); i++) {keys.add("testpipelineM:key_"+i);values.add(String.valueOf(i));}long pipelineStart = System.currentTimeMillis();redisPipeline.plSet(keys,values);long pipelineEnd = System.currentTimeMillis();System.out.println("pipeline操作"+TEST_COUNT+"次字符串數據類型set寫入,耗時:" + (pipelineEnd - pipelineStart) + "毫秒");}
非pipeline操作10000次字符串數據類型set寫入,耗時:4934毫秒
pipeline操作10000次字符串數據類型set寫入,耗時:7毫秒

事務

Redis提供了簡單的事務功能,將一組需要一起執行的命令放到multiexec兩個命令之間。multi 命令代表事務開始,exec命令代表事務結束。另外discard命令是回滾。

multi
sadd sa 1
sadd sb 2
exec


當沒有執行exec的時候,開啟另外一個redis-cli,利用SISMEMBER確認關鍵字是否存在

sismember sa 1
(integer) 0

當執行完exec的時候,開啟另外一個redis-cli,利用SISMEMBER確認關鍵字是否存在

sismember sa 1
(integer) 1

Redis的事務原理

事務是Redis實現在服務器端的行為,用戶執行MULTI命令時,服務器會將對應這個用戶的客戶端對象設置一個特殊的狀態,在這個狀態下后續用戶執行的查詢命令不會被真的執行,而是被服務器緩存起來,直到用戶執行EXEC命令為止,服務器會將這個用戶對應的客戶端對象中緩存的命令按照提交的順序依次執行

Redis的watch命令

有些應用場景需要在事務之前,確保事務中的key沒有被其他客戶端修改過,才執行事務,否則不執行(類似樂觀鎖)。Redis 提供了watch命令來解決這類問題。
在這里插入圖片描述
可以看到“客戶端-1”在執行multi之前執行了watch命令,“客戶端-2”在“客戶端-1”執行exec之前修改了key值,造成客戶端-1事務沒有執行(exec結果為nil)。

Redis客戶端中的事務使用代碼:

 public final static String RS_TRANS_NS = "rts:";@Autowiredprivate JedisPool jedisPool;public List<Object> transaction(String... watchKeys){Jedis jedis = null;try {jedis = jedisPool.getResource();if(watchKeys.length>0){/*使用watch功能*/String watchResult = jedis.watch(watchKeys);if(!"OK".equals(watchResult)) {throw new RuntimeException("執行watch失敗:"+watchResult);}}Transaction multi = jedis.multi();multi.set(RS_TRANS_NS+"test1","a1");multi.set(RS_TRANS_NS+"test2","a2");multi.set(RS_TRANS_NS+"test3","a3");List<Object> execResult = multi.exec();if(execResult==null){throw new RuntimeException("事務無法執行,監視的key被修改:"+watchKeys);}System.out.println(execResult);return execResult;} catch (Exception e) {throw new RuntimeException("執行Redis事務失敗!",e);} finally {if(watchKeys.length>0){jedis.unwatch();/*前面如果watch了,這里就要unwatch*/}jedis.close();}}

Pipeline和事務的區別

PipeLine看起來和事務很類似,感覺都是一批批處理,但兩者還是有很大的區別。簡單來說。

1、pipeline是客戶端的行為,對于服務器來說是透明的,可以認為服務器無法區分客戶端發送來的查詢命令是以普通命令的形式還是以pipeline的形式發送到服務器的;

2、而事務則是實現在服務器端的行為,用戶執行MULTI命令時,服務器會將對應這個用戶的客戶端對象設置為一個特殊的狀態,在這個狀態下后續用戶執行的查詢命令不會被真的執行,而是被服務器緩存起來,直到用戶執行EXEC命令為止,服務器會將這個用戶對應的客戶端對象中緩存的命令按照提交的順序依次執行。

3、應用pipeline可以提服務器的吞吐能力,并提高Redis處理查詢請求的能力。

但是這里存在一個問題,當通過pipeline提交的查詢命令數據較少,可以被內核緩沖區所容納時,Redis可以保證這些命令執行的原子性。然而一旦數據量過大,超過了內核緩沖區的接收大小,那么命令的執行將會被打斷,原子性也就無法得到保證。因此pipeline只是一種提升服務器吞吐能力的機制,如果想要命令以事務的方式原子性的被執行,還是需要事務機制,或者使用更高級的腳本功能以及模塊功能。

4、可以將事務和pipeline結合起來使用,減少事務的命令在網絡上的傳輸時間,將多次網絡IO縮減為一次網絡IO。

Redis提供了簡單的事務,之所以說它簡單,主要是因為它不支持事務中的回滾特性,同時無法實現命令之間的邏輯關系計算,當然也體現了Redis 的“keep it simple”的特性,下一節將介紹的Lua腳本同樣可以實現事務的相關功能,但是功能要強大很多。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91047.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91047.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91047.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何為你的WordPress網站選擇合適的安全插件

在管理WordPress網站時&#xff0c;安全因素至關重要。由于WordPress的廣泛使用&#xff0c;它也成為了黑客攻擊的首要目標。為了避免潛在的安全風險&#xff0c;選擇合適的安全插件至關重要。而Wordfence和iThemes&#xff0c;作為兩款頗具人氣的WordPress安全插件&#xff0c…

我們使用Rust開發的AI知識庫應用

這段時間陸陸續續的開發了2個AI知識庫應用&#xff0c;一個面向企業&#xff0c;一個面向C端用戶。 飛樹智庫&#xff1a;一個安全高效的面向 企業的知識庫平臺&#xff08;https://fskb.coderbox.cn/&#xff09;。 小飛樹&#xff1a;一個專注于個人知識管理的AI應用&#…

自動化測試實戰篇

目錄 1. 自動化實施步驟 1.1 編寫web測試用例 1.2 自動化測試腳本開發 1.3 將自動化測試補充至測試報告 1. 自動化實施步驟 1.1 編寫web測試用例 1.2 自動化測試腳本開發 TestDevelopment: 測試用例 - Gitee.comhttps://gitee.com/Axurea/test-development/tree/master/2…

idea 服務器Debug端口啟動設置

一&#xff1a;在阿里云服務器安全組已經設置了端口授權對象&#xff1a;正確命令&#xff1a;nohup java -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address9998 -jar -Duser.timezoneGMT08 -Xms256m -Xmx256m /opt/projects/*/*/*-starter-1.0-SNAPSHOT.jar -…

大模型量化004

Bert P-tuning BertPET、BertP-Tuning Chain of Thought Few shot Cot Auto-COT 解決手動編寫高質量CoT示例麻煩耗時的問題 Auto COT 自動思維鏈生成器 1.業務場景&#xff1a; 每天收到很多反饋&#xff0c;之前需要人工整理&#xff0c;找到重點&#xff0c;做判斷那些需要立…

C#(基本語法)

數據類型C#是一種強類型語言&#xff0c;變量必須聲明類型。基本數據類型包括整型&#xff08;int、long&#xff09;、浮點型&#xff08;float、double&#xff09;、布爾型&#xff08;bool&#xff09;、字符型&#xff08;char&#xff09;和字符串型&#xff08;string&a…

ARM-I2C軟實現

開發流程引腳初始化引腳功能定義實現讀操作實現寫操作GD32F4軟件I2C初始化void SoftI2C_init() {// 時鐘配置rcu_periph_clock_enable(SCL_RCU);// 設置輸出模式gpio_mode_set(SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCL_PIN);gpio_output_options_set(SCL_PORT, GPIO_O…

防水醫用無人機市場報告:現狀、趨勢與洞察

市場規模與增長趨勢在全球醫療科技快速發展的當下&#xff0c;防水醫用無人機市場正嶄露頭角&#xff0c;展現出強勁的發展勢頭。據 QYR統計&#xff0c;2023 年全球醫用無人機市場銷售額達到 1.9 億美元&#xff0c;預計到 2030 年將飆升至 8.5 億美元&#xff0c;年復合增長率…

haproxy代理

一.負載均衡 1.1.什么是負載均衡 負載均衡&#xff1a;Load Balance&#xff0c;簡稱LB&#xff0c;是一種服務或基于硬件設備等實現的高可用反向代理技術&#xff0c;負載均 衡將特定的業務(web服務、網絡流量等)分擔給指定的一個或多個后端特定的服務器或設備&#xff0c;…

【面試】軟件測試面試題

1. 測試用例如何編寫 2. bug的生命周期 項目有多少人&#xff1f;多少條測試用例&#xff1f;多少bug&#xff1f;自己發現的第一條&#xff1f;&#xff08;是不是bug&#xff09; 3. 缺陷管理工具 包括Jira, PingCode, 禪道&#xff0c;BugZilla&#xff0c;Redmine, TAPD&am…

HbuilderX開發小程序

1.打卡HbuilderX&#xff0c;選擇文件—新建—項目2.創建項目3.在HbuilderX中運行前要確定微信開發這工具的服務端口號是打開的4.HbuilderX中點擊預覽可以實時預覽5.在微信開發者中進行本地測試點擊后自動跳轉到微信開發者工具中運行項目

Netty中FastThreadLocal解讀

io.netty.util.concurrent.FastThreadLocal 是 Netty 中提供的高性能線程局部存儲&#xff08;Thread-Local Storage&#xff09;實現&#xff0c;位于 io.netty.util.concurrent 包。它是 Java 標準庫 ThreadLocal 的替代品&#xff0c;旨在優化性能&#xff0c;減少內存分配和…

上海迪士尼游玩攻略 小鐵寄存柜讓你輕松暢玩

去上海迪士尼玩最煩帶一堆行李&#xff0c;其實有小鐵寄存柜幫忙就能輕裝上陣&#xff0c;各個關鍵位置都有分布&#xff0c;玩起來特別省心。?剛到迪士尼的時候&#xff0c;要是坐地鐵到上海國際旅游度假區站&#xff0c;1/2 號口安檢區就有小鐵柜&#xff0c;行李箱、大背包…

飛算科技重磅出品:飛算 JavaAI 重構 Java 開發效率新標桿

在 Java 開發領域&#xff0c;一款由國家級高新技術企業自主研發的智能工具正引發行業關注 —— 飛算 JavaAI 不僅承載著中國原創技術的創新基因&#xff0c;更以貼合實際開發場景的功能設計&#xff0c;成為眾多企業提升 Java 開發效率的核心助力。?作為飛算數智科技&#xf…

python案例:基于python 神經網絡cnn和LDA主題分析的旅游景點滿意度分析

1&#xff0e;緒論1.1研究背景與意義1.1.1研究背景隨著旅游業的快速發展&#xff0c;滿意度分析成為評估旅游景點質量和提升游客體驗的重要手段。作為中國的旅游城市之一&#xff0c;其旅游景點吸引了大量游客。然而&#xff0c;如何科學評估和提升旅游景點的滿意度&#xff0c…

Git快速入門,完整的git項目管理工具教程,git入門到精通!

Git的下載與安裝&#xff1a; 直接去官網下載即可&#xff1b; 或者查看這個博客學會下載:Git 詳細安裝教程&#xff08;詳解 Git 安裝過程的每一個步驟&#xff09;_git安裝-CSDN博客 注意&#xff1a;一個文件夾下只能有一個本地倉庫(就是一個.git) 細節操作

C++day07(三種取整方法)

學習目標 認識流程圖 多種方式解決問題 取整方式和取整函數 1.解決編程問題的過程 1.理解題意,找出關鍵信息。 2.整理思路,用圖或者文字寫出算法。 3.將算法步驟翻譯為C++代碼。 4.編譯運行,修改語法或邏輯錯誤。 不符合則需要回到上一步進行修改。 5 .輸入測試用例與…

Go語言實戰案例-LRU緩存機制模擬

在高性能服務開發中&#xff0c;緩存是提升訪問速度和減少后端負載的重要手段。常見的緩存淘汰策略中&#xff0c;**LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;**是應用最廣的一種。本篇我們用Go語言手寫一個LRU緩存機制的模擬實現。一、LRU緩存…

vue2中實現leader-line-vue連線文章對應字符

效果展示 通過點擊右邊的tag,觸發連接操作 第一步:獲取右邊tag展示 1.右邊的tag列表展示,我這邊是分為兩個list嵌套的數據結構; {"人員": [{

SPEA2(Strength Pareto Evolutionary Algorithm 2)優化算法簡介

前言 提醒&#xff1a; 文章內容為方便作者自己后日復習與查閱而進行的書寫與發布&#xff0c;其中引用內容都會使用鏈接表明出處&#xff08;如有侵權問題&#xff0c;請及時聯系&#xff09;。 其中內容多為一次書寫&#xff0c;缺少檢查與訂正&#xff0c;如有問題或其他拓展…