MySQL作為新的NoSQL解決方案:輕鬆應對億級資料
MySQL現在是一個更好的NoSQL解決方案。我們這樣說是因為在儲存 鍵/值(key/value) 之類資料時, MySQL 具有效能、易用性和穩定性方面的優勢。MySQL引擎穩定可靠,並且社群和官方支援良好,有非常豐富的線上資料, 涵蓋了各種操作、故障排查,複製以及各種使用模式等方面。基於這個原因, MySQL比起新興的NoSQL引擎具有很大優勢。
近年來,NoSQL引擎已成為主流。許多開發者將NoSQL引擎(包括: MongoDB, Cassandra, Redis, 和 Hadoop等)視為最優解,同時不贊成使用舊的 SQL 引擎。
選擇NoSQL資料庫通常是因為炒作,或者是認為關係資料庫解決不了和NoSQL相關的事。普通工程師在選擇資料庫時往往會忽視運營成本,穩定性和成熟度等問題。更多關於各種NoSQL(以及SQL)引擎的區別,以及侷限性等方面的問題,請參考 Aphyr 上的 Jepsen專欄文章。
本文將闡釋為什麼用MySQL儲存 鍵/值 資料比大多數專用NoSQL引擎更適合的原因,並提供相應的指導步驟。
Wix 網站的解決方案
當用戶訪問Wix上的某個網站頁面時, 瀏覽器會向Wix網站伺服器傳送一個HTTP請求。不管是自定義域名(例如, cncounter.com)還是免費的Wix二級域名(如: user.wix.com/site)。伺服器需要通過查詢鍵/值對來將URL請求解析為相應的站點。在下面的討論中我們將URL視為 route(路由)。
routes 表用來將網址解析為 site 物件。因為網站可能有多個路由, 所以是多對一的關係(many to one, N:1)。找到網站以後, 程式就載入它。site 物件機構比較複雜, 包括兩個子物件列表 —— 網站使用的不同服務。下面是示例物件模型, 假設使用標準SQL資料庫和規範化表結構:
當更新 site時, 如果使用傳統的正規化模型來更新多個表, 需要用事務(transaction)來保證資料的一致性(data consistency)。(注意,事務使用資料庫級別的鎖(DB-level lock),這會阻止併發寫操作,有時也會影響相關表的併發讀操作。) 使用這種模型, 可能需要在每個表中設定一個序列鍵(serial key),並使用外來鍵,以及為 routes 表的 URL 欄位建立索引。
但是,使用正規化設計會碰到很多問題:
- 鎖限制了對錶的訪問, 所以在高吞吐量情景下會嚴重影響效能。
- 讀取一個物件需要使用多條SQL語句(此處是4條), 或者使用 join (這又會受延遲影響)。
- 系列鍵的生成使用了鎖, 限制了寫吞吐量。
在MySQL或者其他SQL引擎中, 併發情況和吞吐量問題都是大量出現的。因為這些缺點,實際上在儲存 鍵/值對形式的資料時,很多開發者都傾向於使用 NoSQL 解決方案, 為了提供更好的吞吐量和併發效能, 而犧牲一些 穩定性(stability)、一致性(consistency)、和可用性(availability)。
在 Wix, 我們發現 MySQL 作為鍵/值儲存使用時,比起作為關係資料模型時要強悍得多, 也比大多數NoSQL引擎要優秀很多。僅僅是使用MySQL作為NoSQL引擎,我們的現有系統在擴充套件性/吞吐量/併發/延遲等指標上都可以媲美任何NoSQL引擎。下面是一些資料:
- 跨三個資料中心的結構 (active-active-active setup, 三活)。
- 吞吐量在 200,000 RPM 數量級。
- routes 表的記錄在 1億 數量級, 佔用空間為 10 GB級。
- sites 表的記錄在 1億數量級,儲存空間 200 GB以上。
- 平均讀取延遲在 1.0 -1.5毫秒之間(事實上,同一資料中心是 0.2 - 0.3 毫秒)。
請注意,在大多數 鍵/值 引擎中, 1.0 毫秒左右的延遲都是卓越的,包括開源的和基於雲的! 而我們是用MySQL實現的(MySQL被認為是標準的SQL引擎)。
表結構如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CREATE
TABLE
`routes` (
`route`
varchar
(255)
NOT
NULL
,
`site_id`
varchar
(50)
NOT
NULL
,
`last_update_date`
bigint
NOT
NULL
,
PRIMARY
KEY
(`
key
`),
KEY
(`site_id`)
)
CREATE
TABLE
`sites` (
`site_id`
varchar
(50)
NOT
NULL
,
`owner_id`
varchar
(50)
NOT
NULL
,
`schema_version`
varchar
(10)
NOT
NULL
DEFAULT
'1.0'
,
`site_data` text
NOT
NULL
,
`last_update_date`
bigint
NOT
NULL
,
PRIMARY
KEY
(`site_id`)
)
/*ENGINE=InnoDB DEFAULT CHARSET=utf8
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=16*/
;
所有不需要作為查詢條件的欄位都已經合併到單個 blob 欄位中(site_data text 欄位)。其中包含了 sub-obj 記錄,以及 site 物件自身的其他屬性域。也請注意,這裡沒有使用自增序列鍵;相反,我們使用 varchar(50) 來儲存客戶端生成的 GUID 值。
下面是我們使用的查詢語句, 具有高吞吐量和低延遲特性:
?1 2 3 select
*
from
sites
where
site_id = (
select
site_id
from
routes
where
route = ?
)
首先通過唯一索引查詢 routes 表,這隻返回一個結果。然後通過主鍵查詢 site, 也只有一條記錄。巢狀查詢語法確保 2個SQL查詢卻只需一次資料庫互動。
結果前面提到了, 在高流量和高更新率的情況下, 保持在平均 ~1毫秒左右 的效能。雖然沒有使用事務,但 update 是半事務性質的(semi-transactional)。這是因為, 先輸入一個 site, 但在輸入 route 記錄之前,都不會查詢到相關的記錄。所以如果我們先輸入 site, 再輸入 route, 依然能確保資料一致性狀態, 即使在 sites 表中有很多孤兒資料的情況下。
MySQL當做 NoSQL引擎使用指南
通過上面的例子(以及Wix的其他類似情景), 我們精心製作了一份用MySQL作為NoSQL引擎的經驗指南。
最主要的是要記住, 使用MySQL作為NoSQL引擎時要避免資料庫鎖(DB locks)以及複雜的查詢。
- 不使用事務,因為會導致鎖(locks)。相反, 應該使用應用層事務(applicative transactions)。
- 不使用序列鍵(serial key)。序列鍵會導致鎖以及引起復雜的 active-active 配置。
- 使用客戶端生成的唯一鍵(client-generated unique keys)。我們使用的是 GUID。
設計資料庫時,進行查詢優化時還有如下要點:
- 不要使用正規化(Do not normalize)。
- 只儲存有索引的欄位。如果某個欄位不需要索引, 那麼將其儲存在 blob/text 欄位中(如JSON或XML)。
- 不要使用外來鍵(foreign key)。
- 必須允許讀取單行資料。
- 不準執行 alter 命令。表的 alter 命令會導致鎖以及宕機。如果不得不這樣做, 應該使用動態遷移(live migrations)。
在查詢資料時:
- 使用主鍵(primary key)和索引(index)作為條件來查詢.
- 不要使用 join.
- 不要使用聚合函式(aggregation).
- 只在副本(replica)中執行繁重的查詢(housekeeping queries), 比如商業智慧(BI), 資料研究(data exploration)等操作, 儘量不要在主庫(master database)上執行.
我們準備在另一篇部落格中深入介紹實時遷移(live migrations)和應用層事務(applicative transactions)。
總結
本文最主要的目的是讓你認識 MySQL 的新特性。將 MySQL 作為NoSQL引擎是很棒的, 雖然MySQL不是專為NoSQL設計的。文中展示瞭如何使用 MySQL 代替專用 NoSQL引擎來儲存 鍵/值(key/value) 資訊。
在 Wix , 儲存鍵/值資訊(等情況下)會選擇MySQL引擎, 原因是其易於使用和操作, 並且MySQL強大的生態系統。另外,比起多數NoSQL引擎來說,在延遲(latency)、吞吐量(throughput)和併發性(concurrency)等指標(metrics)上MySQL並不遜色。
相關推薦
MySQL作為新的NoSQL解決方案:輕鬆應對億級資料
MySQL現在是一個更好的NoSQL解決方案。我們這樣說是因為在儲存 鍵/值(key/value) 之類資料時, MySQL 具有效能、易用性和穩定性方面的優勢。MySQL引擎穩定可靠,並且社群和官方支援良好,有非常豐富的線上資料, 涵蓋了各種操作、故障排查,複製以及各種
MySQL 作為新的 NoSQL 解決方案: 輕鬆應對億級資料
MySQL現在是一個更好的NoSQL解決方案。我們這樣說是因為在儲存 鍵/值(key/value) 之類資料時, MySQL 具有效能、易用性和穩定性方面的優勢。MySQL引擎穩定可靠,並且社群和官方支援良好,有非常豐富的線上資料, 涵蓋了各種操作、故障排查,複製以及各種使用
基於分散式關係型資料庫,實現輕鬆應對百億級資料分析場景解決方案
MyCat是什麼? 從定義和分類來看,它是一個開源的分散式資料庫系統,是一個實現了MySQL協議的伺服器,前端使用者可以把它看作
window.open打開一個新空白頁面,不會自動刷新【解決方案】
form turn targe push .get action html pos bstr 調用js方法: function BuildPostForm(fm, url, target) { var e = null, el = []; if (
MYSQL讀寫分離解決方案:MariaDB MaxScale部署實錄
maxscaleMASTER(KING01)[root@king01 ~]# mysql -uroot -pabcd.1234 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 173 S
MYSQL讀寫分離解決方案:MYCAT部署實錄
mysql mycat 讀寫分離 MASTER (KING01)[root@king01 ~]# mysql -uroot -pabcd.1234 mysql> show master status; +------------------+----------+--------------
高並發大容量NoSQL解決方案探索
nosql sql mysql 大數據時代,企業對於DBA也提出更高的需求。同時,NoSQL作為近幾年新崛起的一門技術,也受到越來越多的關註。本文將基於個推SRA孟顯耀先生所負責的DBA工作,和大數據運維相關經驗,分享兩大方向內容:一、公司在KV存儲上的架構演進以及運維需要解決的問題;二、對NoS
大容量NoSql解決方案:Aerospike實戰
技術 能夠 部署 結果 接口 碎片 數量 get family 個推專註為開發者們提供消息推送服務多年。通過個推SDK,手機終端與服務器建立長連接,維持在線狀態。然而在網絡異常等情況下,消息無法實時送達到終端用戶,因而推送服務器建立了一份離線消息列表,以待用戶重新登錄時,進
MySQL服務無法啟動解決方案
MySql免安裝版安裝配置,附MySQL服務無法啟動解決方案 - 陳大VV - 部落格園 陳大VV
Filenet:ipfs網路激勵層一種新的解決方案
人有不當好人的權利,可是如果別人想當好人,我們起碼不要去做洩氣的旁觀者。 ----考慮到Filecoin在當下的影響,中立的表達對新激勵層的看法 今年慢熊市,大家對挖礦都失去了信心,不過有兩樣東西是共識的熱點,一是EOS超級節點,另一個就是IPFS。 我們知道,第一批挖
mysql 遇到問題及解決方案
用localhost 和127.0.0.1可以連線資料庫,用IP不可以連線[MySQL資料庫版本:5.7.20]: 原因: MySQL 預設是沒有開啟這個許可權的(只允許使用 host:localhost或者 host:127.0.0.1),如果想用host:192.168.1.* ,來
mysql連線數過多 解決方案 閱讀目錄
導致原因: 檢視連結: 解決方法: 模擬mysql連線數過多 mysql 預設連結數是100個 最大是16384。 原則:想盡一切辦法不重啟 回到頂部 導致原因: 出現這種錯誤明顯就是 mysql_connect 之後忘記 mys
Mysql無法遠端連線解決方案
前言 Mysql 版本:5.7.23作業系統:Linux問題描述:只能通過Linux系統賬號Root命令列進入資料庫,無法使用JDBC,遠端連線工具進入資料庫。報錯:ERROR 1698 (28000): Access denied for user 'root'@'localhost'這個問題明顯就是沒有
MySql免安裝版安裝配置以及MySQL服務無法啟動解決方案
MySql免安裝版安裝配置以及MySQL服務無法啟動解決方案 文首提要: 下載的MySQL版本是:mysql-5.7.17-winx64.zip &n
Mysql容器啟動失敗-解決方案
conf mage 重要 als 查看 director 一次 ops star 在看問題之前首先熟悉幾個命令 相關命令 1.docker attach 連接到正在運行中的容器; 命令:docker attach --sig-proxy=false mynginx
java Mysql 儲存emoji表情解決方案
引用emoji-java.jar <!-- emjoy 表情過濾 --> <dependency> <groupId>com.vdurmont</groupId> <artifactId>emoji-java
忘記本地MySQL資料庫密碼的解決方案。
忘記本地MySQL資料庫密碼,解決方案,分以下10個步驟: 參考連結:https://blog.csdn.net/weidong_y/article/details/80493743 資料庫版本:5.7.21 1、開啟cmd視窗,進入 MySQL的安裝目錄。 2、停止MySQL的服務。已經停止了。
連線mysql報錯#1251解決方案
真的是很激動,修改了好幾天mysql與其使用工具的連線問題,終於修改成功 錯誤問題是本地的mysql服務加密方式有問題,在使用工具上會報錯#1251的錯誤 修改方法: 1. 建議將之前的mysql服務刪除掉,具體刪除方法網上很全 2.安裝好新的mysql後,c
navicat連線mysql報錯1251解決方案
今天下了個 MySQL8.0,發現Navicat連線不上,總是報錯1251; 原因是MySQL8.0版本的加密方式和MySQL5.0的不一樣,連線會報錯。 試了很多種方法,終於找到一種可以實現的: 更改加密方式 1.先通過命令列進入mysql的root賬戶:
Mysql 1205 Error 錯誤解決方案
#Java執行一個SQL插入的時候,遇到1205錯誤。 java.lang.Exception: ### Error updating database. Cause: java.sql.SQLException: Lock wait timeout exceeded; try re