Redis主從結構主節點執行寫入後wait命令對性能的影響

来源:https://www.cnblogs.com/wy123/archive/2020/01/06/12158957.html
-Advertisement-
Play Games

這裡的Redis主從結構可以是簡單的主從,sentinel,redis cluster中的主從等。wait命令的作用:此命令將阻塞當前客戶端,直到當前Session連接(主節點上)所有的寫命令都被傳送到指定數據量的slave節點。如果到達超時(以毫秒為單位),則即使尚未完全傳送到達指定數量的salv ...


這裡的Redis主從結構可以是簡單的主從,sentinel,redis cluster中的主從等。

wait命令的作用:
此命令將阻塞當前客戶端,直到當前Session連接(主節點上)所有的寫命令都被傳送到指定數據量的slave節點。
如果到達超時(以毫秒為單位),則即使尚未完全傳送到達指定數量的salve節點,該命令也會返回(成功傳送到的節點的個數)。
該命令將始終返回確認在WAIT命令之前發送的寫命令的副本數量,無論是在達到指定數量的副本的情況下,還是在達到超時的情況下。
具體說就是:比如對於1主2從的結構,Wait要求3秒鐘之內傳送到2個節點,但是達到超時時間3秒鐘之後只成功傳送到了1個slave節點上,此時wait也不會繼續阻塞,而是返回成功傳送的節點個數(1)。
有點類似於MySQL的半同步複製,但是效果完全不能跟半同步相比,因為Redis本身沒有回滾的功能,這裡的wait命令發起之後,即便是超時時間之後沒有送到任何一個slave節點,主節點也不會回滾。
wait命令無法保證Redis主從之間的強一致,不過,在主從、sentinel和Redis群集故障轉移中,wait能夠增強(僅僅是增強,但不是保證)數據的安全性。

既然wait命令在當前連接之後會等待指定數量的從節點確認,其主節點的寫入效率必然會收到一定程度的影響,那麼這個影響有多大?
這裡做一個簡單的測試,環境2核4G的宿主機,docker下的集群3主3從的Redis集群,因此不用考慮網路延遲,在執行寫入操作之後,使用兩個Case,對比使不使用wait命令等待傳送到salve的效率,
1,單線程迴圈寫入100000個key值
2,多線程併發,10個線程每個線程寫入10000個key,一共寫入100000個key

Case1:單線程迴圈寫入100000個key值
結論:不使用wait命令,整體耗時33秒,集群中單個節點的TPS為1000左右;使用wait命令,整體耗時72秒,集群中單個節點的TPS為480左右,整體效率下降了50%多一點

單線程不使用WAIT

單線程使用WAIT(redis_conn.execute_command('wait', 1, 0))

 

Case2:多線程迴圈寫入100000個key值
結論:不使用wait命令,整體耗時19秒,集群中單個節點的TPS為1700左右;使用wait命令,整體耗時36秒,集群中單個節點的TPS為900左右,整體效率與單線程基本上一致,下降了50%多一點

多線程不使用WAIT,單節點上TPS可達到1700左右

多線程使用WAIT,單節點上TPS可達到850左右

鑒於在多線程模式下,CPU負載接近於瓶頸,因此不能再加更多的線程數,測試數據也僅供參考。

 

總結:
wait能夠在主節點寫入命令之後,通過阻塞的方式等待數據傳送到從節點,wait能夠增強(但不保證)數據的安全性。
其代價或者說性能損耗也是不小的,通過以上測試可以看出,即便是不考慮網路傳輸延遲的情況下,其性能損耗也超出了50%。

#!/usr/bin/env python
# coding:utf-8
import sys
import time
import datetime
from rediscluster import StrictRedisCluster
import threading
from time import ctime,sleep


def redis_cluster_write():
    redis_nodes = [ {'host':'172.18.0.11','port':8888},
                    {'host':'172.18.0.12','port':8888},
                    {'host':'172.18.0.13','port':8888},
                    {'host':'172.18.0.14','port':8888},
                    {'host':'172.18.0.15','port':8888},
                    {'host':'172.18.0.16','port':8888}]
    try:
        redis_conn = StrictRedisCluster(startup_nodes=redis_nodes,password='******')
    except Exception:
        raise Exception
    redis_conn.config_set('cluster-require-full-coverage', 'yes')
    counter = 0
    for i in range(0,100000):
        counter = counter+1
        redis_conn.set('key_'+str(i),'value_'+str(i))
        #redis_conn.execute_command('wait', 1, 0)
        if counter == 1000:
            print('insert 1000 keys '+str(str(datetime.datetime.now())))
            counter = 0


def redis_concurrence_test(thread_id):
    redis_nodes = [ {'host':'172.18.0.11','port':8888},
                    {'host':'172.18.0.12','port':8888},
                    {'host':'172.18.0.13','port':8888},
                    {'host':'172.18.0.14','port':8888},
                    {'host':'172.18.0.15','port':8888},
                    {'host':'172.18.0.16','port':8888}]
    try:
        redis_conn = StrictRedisCluster(startup_nodes=redis_nodes, password='******')
    except Exception:
        raise Exception
    redis_conn.config_set('cluster-require-full-coverage', 'yes')
    counter = 0
    for i in range(0, 10000):
        counter = counter + 1
        redis_conn.set('key_' + str(thread_id)+'_'+str(counter), 'value_' + str(i))
        #redis_conn.execute_command('wait', 1, 0)
        if counter == 1000:
            print(str(thread_id)+':insert 1000 keys ' + str(str(datetime.datetime.now())))
            counter = 0



if __name__ == '__main__':
    #redis_cluster_write()
    threads = []
    for i in range(10):
        t = threading.Thread(target=redis_concurrence_test, args=(i,))
        threads.append(t)
    begin_time = ctime()
    for t in threads:
        t.setDaemon(True)
        t.start()
    for t in threads:
        t.join()


https://redis.io/commands/wait


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近在安裝python3 時升級openssl 版本,在摸索openssl 升級過程中才發現centos6 預設安裝的openssl 1.0.1e 版本是有一個嚴重的漏洞的(Padding oracle in AES-NI CBC MAC check (CVE-2016-2107)),建議用open ...
  • 在企業的相關設置中,若兩台物理機,主副之間需要做到文件同步,可以推薦使用Freefilesync作為自動同步設置 話不多說,直接搞機 開始設置好文件比對-點擊紅色漏斗設置(比較/同步) 點擊確定 手動同步完成 自動同步 將剛剛設置的同步保存為一個批處理文件 目錄欄處-文件-另存為批處理文件 記得設置 ...
  • 文字是一種思維病毒 因為它可以改寫大腦的迴路 書寫是為了更好的思考 “教”是最好的“學” 一旦你把自己潛意識裡面的東西從幕後拉出來,你就有了面對並反思它們的可能,而不是任它們在幕後陰險地左右你的思維 無論如何,不用急於求成,在一個主題上深入下去思考,總能挖到別人挖不到的角落。你能讓一個問題在大腦中停 ...
  • everspin MRAM是為LSI Corporation(現在的Avago Technologies)RAID控制器卡上的日誌存儲器選擇的存儲器,該RAID卡具有6Gb/s和12Gb/sSAS存儲連接。Everspin MRAM在其RAID磁碟陣列中執行寫日誌或數據日誌功能。 MRAM實時捕獲事 ...
  • 自旋轉矩磁阻隨機存取存儲器(ST-MRAM)有望成為一種快速,高密度的非易失性存儲器,可以增強各種應用程式的性能,特別是在用作數據存儲中的非易失性緩衝器時設備和系統。為此,everspin開發了基於90nmCMOS技術的全功能64Mb DDR3 STT-MRAM。存儲器以8個存儲區的配置進行組織,可 ...
  • 參考穀粒學院的linux視頻教程:http://www.gulixueyuan.com/course/300/task/7091/show ...
  • 目錄 一、安裝前準備 二、安裝MySQL 三、設置遠程登錄 四、安裝問題解決 五、設置MySQL開機自啟 一、安裝前準備 1、在官網下載MySQL安裝包(註意下載的安裝包類型) 2、查看是否安裝mariadb # rpm -qa | grep mariadb 3、卸載mariadb # rpm -e ...
  • 目錄 一、###MySQL登錄和退出 二、###MySQL常用命令 三、###MySQL語法規範 四、###基礎查詢 五、###條件查詢 六、###排序查詢 七、###常見函數的學習 八、###分組查詢 九、###連接查詢 十、###子查詢 十一、###分頁查詢 十二、###聯合查詢 十三、###D ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...