只更新一次的行表值得分片嗎?
我有一個包含使用者請求的大型 MySQL 5.6 Inno DB 表。
一個表行只更新一次,在初始插入之後不久!
(初始插入是為了獲取唯一的自增request_id,以便對請求進行處理)
創建表
requests
(
id
bigint(20) NOT NULL AUTO_INCREMENT,
user_id
BIGINT 不為空,
date
時間戳 NOT NULL DEFAULT CURRENT_TIMESTAMP,
request
文本
data
文本,) 引擎 InnoDB AUTO_INCREMENT=1 預設字元集=latin1
偽腳本程式碼如下:
執行(“插入請求(id)值(預設)”)
我的 $id = query(“SELECT LAST_INSERT_ID()”)
我的 $ data = do_some_fast_processing( $ id,$查詢)
執行(qq# UPDATE請求SET查詢=" $ query", data= $ 數據在哪裡 id=$id #)
每天大約有 1000 萬個請求。意味著 1000 萬個“插入然後更新”實例。假設我將其分片為 2(奇/偶使用者 id),並假設兩個分片將完成每天一半的請求,我會獲得顯著/有價值的寫入性能嗎?因為沒有鎖?還假設我的機器 IO 沒有達到最大值。
有問題嗎?還是您期望顯著增長?10M/day = 120/second,很高,但不一定是極限。
innodb_flush_log_at_trx_commit = 1 是最安全的,但也是最慢的。值為 2 將提高性能。
批處理 INSERT 也是一種性能提升;但是,由於您的應用程序的工作方式,您可能無法這樣做。如果可行的話,將語句組合到事務中也會有所幫助。
您對應用程序的描述聽起來像是所有活動都集中在一張桌子的“末端”附近。這意味著幾乎沒有 I/O(除了事務日誌,這就是我上面提到的)。
回到你的問題…
跨 N 台伺服器進行分片將減少近 N 倍的 I/O、鎖定、CPU 等。
決定去哪個分片的過程應該是另一台機器,並且分片應該在每台機器上都是單獨的。
分片處理增長的一個問題是當你需要超過 N 台機器時該怎麼做。
我們顯然沒有足夠的資訊來回答你的問題,但我會盡量給你一些通用的建議。
你說你每秒有 1000 萬個請求。這不是一個令人印象深刻的數字(儘管對於小型機器來說可能太多了,所以我們沒有足夠的資訊)。但這裡真正重要的是,在高峰期你每秒有多少請求?
你擔心
AUTOINC
鎖。您可以通過定期查詢performance_schema.data_locks
表來監控導致爭用的鎖的頻率。如果您需要減少爭用,請檢查 的值
innodb_autoinc_lock_mode
。理想情況下它應該是 2,但這需要binlog_format=ROW
而不是重放二進制日誌(如果你不理解這部分,你是安全的)。假設你有一個由
AUTOINC
鎖引起的爭用問題,你也可以做一些完全不同的事情:使用 UUID 代替AUTO_INCREMENT
主鍵。這樣,生成唯一值的責任就委託給了應用程序,MySQL 將不必為此目的獲取特殊鎖。每次插入都會慢一點,不多,但無論如何我建議在生產中實現它之前測試這個想法。