<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        UsingMySQLasaNoSQL_MySQL

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-09 19:54:29
        文檔

        UsingMySQLasaNoSQL_MySQL

        UsingMySQLasaNoSQL_MySQL:NoSQL FROM: Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server 由于 MySQL 的局限性,很多站點(diǎn)都采用了 MySQL+Memcached 的架構(gòu)。另外一些站點(diǎn)放棄 MySQL 而采用 NoSQL,比如 TokyoCa
        推薦度:
        導(dǎo)讀UsingMySQLasaNoSQL_MySQL:NoSQL FROM: Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server 由于 MySQL 的局限性,很多站點(diǎn)都采用了 MySQL+Memcached 的架構(gòu)。另外一些站點(diǎn)放棄 MySQL 而采用 NoSQL,比如 TokyoCa

        NoSQL

        FROM: Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server
          由于 MySQL 的局限性,很多站點(diǎn)都采用了 MySQL+Memcached 的架構(gòu)。另外一些站點(diǎn)放棄 MySQL 而采用 NoSQL,比如 TokyoCabinet/Tyrant 等。不可否認(rèn),在做一些簡(jiǎn)單查詢(xún) (尤其 PK 查詢(xún)) 的時(shí)候,NoSQL 比 MySQL 要快很多很多。而且網(wǎng)站上的絕大多數(shù)查詢(xún)都是這樣的簡(jiǎn)單查詢(xún)。
          像其他大規(guī)模的公司一樣,DeNA 也面臨過(guò)類(lèi)似的問(wèn)題。但最后我們采用的是一完全不同的方法, 僅使用了 MySQL。我們?nèi)匀皇褂?Memcached 做前端緩存(例如,預(yù)處理 HTML, 數(shù)量/摘要 信息),但在后端,既沒(méi)有使用 Memcached 緩存任何記錄,也沒(méi)有使用 NoSQL,這是為什么呢?因?yàn)榕c其他的 NoSQL 產(chǎn)品相比,我們的 MySQL 能得到更好的性能。 在我們的基準(zhǔn)測(cè)試中,一普通的 MySQL/InnoDB 5.1 服務(wù)器達(dá)到了 750,000+ QPS,生產(chǎn)環(huán)境中的性能當(dāng)然更不列外。或許,你們很難相信這個(gè)數(shù)字,但這是事實(shí)。我將在以下分享我們的經(jīng)驗(yàn)。
          (作者經(jīng)歷)2010-08,我離開(kāi)了 Oracle, 現(xiàn)在任職于日本最大社交游戲平臺(tái)供應(yīng)商之一的 DeNA。
          在每秒中,需要做多少次的 PK 查詢(xún)了?在 DeNA 公司的應(yīng)用中,經(jīng)常要進(jìn)行 PK 查詢(xún)。比如根據(jù) user id 取出 userinfo,根據(jù) diary id 取出日志內(nèi)容, 對(duì)于這樣的需求,不用說(shuō),Memcached 和 NoSQL 都相當(dāng)適合。在簡(jiǎn)單的多線程 “Memcached GET”基準(zhǔn)測(cè)試中,很可能每秒進(jìn)行 400,000 次 get 操作,即使 Memcached client 在不同的服務(wù)器。在一臺(tái) Nehalem box 2.5GHz x 8 核 CPU, Broadcom 四端口千兆網(wǎng)卡的服務(wù)器上,最新的 libMemcached 和 Memcached 每秒可達(dá)到 420,000 次 get 操作。
          在 MySQL 下, 每秒可作多少次的 PK 查詢(xún)呢, 我們可用 sysbench, super-smack or mysqlsla 等來(lái)進(jìn)行基準(zhǔn)測(cè)試
        [matsunobu@host ~]$ mysqlslap --query="select user_name,.. from test.user where user_id=1" \\
        --number-of-queries=10000000 --concurrency=30 --host=xxx -uroot
        
          通過(guò)如下命令,很快就得知 InnoDB 的 QPS 大概為 100,000, 幾乎只有 Memcached 的 1/4.
        [matsunobu@host ~]$ mysqladmin extended-status -i 1 -r -uroot \\
        | grep -e "Com_select"
        
        ...
        | Com_select | 107069 |
        | Com_select | 108873 |
        | Com_select | 108921 |
        | Com_select | 109511 |
        | Com_select | 108084 |
        | Com_select | 108483 |
        | Com_select | 108115 |
        ...
        
          看上去, 100, 000+ QPS 也不是太差,但為什么 MySQL 比 Memcached 差這么多呢,MySQL 到底在做什么呢。從 vmstat 的統(tǒng)計(jì)信息得知, %user 和 %system 的數(shù)據(jù)都非常高.
        [matsunobu@host ~]$ vmstat 1
        
        r b swpd free buff cache in cs us sy id wa st
        23 0 0 963004 224216 29937708 58242 163470 59 28 12 0 0
        24 0 0 963312 224216 29937708 57725 164855 59 28 13 0 0
        19 0 0 963232 224216 29937708 58127 164196 60 28 12 0 0
        16 0 0 963260 224216 29937708 58021 165275 60 28 12 0 0
        20 0 0 963308 224216 29937708 57865 165041 60 28 12 0 0
        
          再看 Oprofile 輸出,可知 CPU 消耗的出去:
        samples % app name symbol name
        259130 4.5199 mysqld MYSQLparse(void*)
        196841 3.4334 mysqld my_pthread_fastmutex_lock
        106439 1.8566 libc-2.5.so _int_malloc
        94583 1.6498 bnx2 /bnx
        284550 1.4748 ha_innodb_plugin.so.0.0.0 ut_delay
        67945 1.1851 mysqld _ZL20make_join_statisticsP4JOINP10TABLE_LISTP4ItemP16st_dynamic_array
        63435 1.1065 mysqld JOIN::optimize()
        55825 0.9737 vmlinux wakeup_stack_begin
        55054 0.9603 mysqld MYSQLlex(void*, void*)
        50833 0.8867 libpthread-2.5.so pthread_mutex_trylock
        49602 0.8652 ha_innodb_plugin.so.0.0.0 row_search_for_mysql
        47518 0.8288 libc-2.5.so memcpy
        46957 0.8190 vmlinux .text.elf_core_dump
        46499 0.8111 libc-2.5.so malloc
        
          MySQL 的 SQL 解析階段,有調(diào)用 MYSQLparse() 和 MYSQLlex(); 查詢(xún)優(yōu)化階段,調(diào)用 make_join_statistics() 和 JOIN::optimize()。很明顯,主要耗資源的是SQL 層,而不是 InnoDB 存儲(chǔ)層。與 Memcached/NoSQL 比起來(lái),MySQL 還要額外做一些工作:
        Parsing SQL statements 解析 SQL.
        Opening, locking tables 打開(kāi)并鎖定表.
        Making SQL execution plans SQL 執(zhí)行計(jì)劃.
        Unlocking, closing tables 解鎖并關(guān)閉表.

          另外,MySQL 還必須要做大量的并發(fā)控制,比如在發(fā)送/接收網(wǎng)絡(luò)數(shù)據(jù)包的時(shí)候,fcntl() 就要被調(diào)用很多次; Global mutexes 比如 LOCK_open,LOCK_thread_count 也被頻繁地取得/釋放。所以, 在 Oprofile 的輸出中,排在第二位的是 my_pthread_fastmutex_lock()。并且 %system 占用的 CPU 相當(dāng)高(28%)。

          其實(shí) MySQL 開(kāi)發(fā)團(tuán)隊(duì)和外圍的開(kāi)發(fā)團(tuán)體已意識(shí)到大量并發(fā)控制對(duì)性能的影響,MySQL5.5 中已經(jīng)解決了一些問(wèn)題。未來(lái)的 MySQL 版本中,應(yīng)該會(huì)越來(lái)越好。

          還有一個(gè)大的問(wèn)題是,%user 達(dá)到了60%。互斥量的爭(zhēng)奪導(dǎo)致 %system 上增,而不是 %user,即使 MySQL 內(nèi)部關(guān)于互斥量的的問(wèn)題都得到修復(fù),還是很難達(dá)到我們所期望的 300,000 QPS.也許,會(huì)有人提到使用 HANDLER ,但是因?yàn)樵诮馕?SQL時(shí),opening/closing table 還是必須的,所以對(duì)于提高吞吐量,它還是只能愛(ài)莫能助。

          如果只有一小部分?jǐn)?shù)據(jù)進(jìn)入內(nèi)存,那么 SQL 帶來(lái)的消耗可以忽略不計(jì)。很簡(jiǎn)單,因?yàn)榇疟P(pán)的 I/0 操作所帶來(lái)的消耗會(huì)要大,這種情況下時(shí),就不需要太過(guò)的去考慮 SQL 所帶來(lái)的消耗。

          但是,在大多數(shù)的 hot MySQL 服務(wù)器中, 大部分的數(shù)據(jù)都是因?yàn)槿枯d入至內(nèi)存中而變的只受 CPU 的限制。Profiling 的結(jié)果就類(lèi)似上所述的那樣: SQL 層消耗了大量的資源。假設(shè),需要做大量的 PK 查詢(xún)(i.e. SELECT x FROM t WHERE id=?)或者是做 LIMIT 的范圍查詢(xún), 即使有 70-80% 都是在同一張表中做 PK 查詢(xún)(僅僅只是查詢(xún)條件中給定的值不同,即 value 不同而已), MySQL 還是每次需要去做 parse/open/lock/unlock/close, 這對(duì)我們來(lái)說(shuō),是非常影響效率的。

          到底有沒(méi)有好的方法來(lái)減少 MySQL SQL 層的 CPU 資源/爭(zhēng)奪呢? 如果使用 MySQL Cluster, NDBAPI 不失為一個(gè)很好的解決辦法。 在我還是 MySQL/Sun/Oracle 的顧問(wèn)時(shí),就見(jiàn)到過(guò)很多客戶(hù)對(duì)SQL Node + NDB performance 感到非常不爽,但當(dāng)他們用了 NDBAPI 客戶(hù)端后,發(fā)現(xiàn)性能調(diào)提高了 N 倍。當(dāng)然,在 MySQL Cluster 中是可以同時(shí)使用 NDBAPI 和 SQL 的,但在做頻繁的訪問(wèn)模式時(shí)還是推薦使用 NDBAPI,而在 ad-hoc 或者 查詢(xún)不頻繁的情況下使用 SQL + MySQL + NDB。

          以快捷的速度訪問(wèn) API, 這正是我們需要的,但同時(shí)我們也想在 ad_hoc 或者復(fù)雜的查詢(xún)的情況時(shí)還是使用 SQL. 像其他的 web service, DeNA 使用的是 InnoDB, 轉(zhuǎn)為 NDB,這并不是一件容易的事情,因?yàn)閮?nèi)置InnoDB 即不支持 SQL 也不支持網(wǎng)絡(luò)層的服務(wù)。

          最好的辦法可以是在 MySQL 的內(nèi)部,實(shí)現(xiàn)一以 MySQL plugin 的形式存在的 NoSQL 的網(wǎng)絡(luò)服務(wù)。它偵聽(tīng)在某端口來(lái)接收采用 NoSQL 協(xié)議/API 的通訊, 然后通過(guò) MySQL 內(nèi)部的存儲(chǔ)引擎 API 來(lái)直接訪問(wèn) InnoDB。這種方法的理念類(lèi)似于 NDBAPI, 但是它可以做到與 InnoDB 通訊。

          這個(gè)理念最初是去年由 Kazuho Oku 在 Cybozu Labs 上提出的,他曾寫(xiě)過(guò)采用 Memcached protocols 通訊的MyCached UDF。而我的大學(xué)同學(xué)實(shí)現(xiàn)了另外一個(gè)插件 ― HandlerSocket,

          是以 MySQL daemaon plugin 形式存在,所以在應(yīng)用中可把 MySQL 當(dāng) NoSQL 使用. 它最大的功能是實(shí)現(xiàn)了與存儲(chǔ)引擎交互,比如 InnoDB,而這不需要任何的 SQL 方面的開(kāi)銷(xiāo). 訪問(wèn) MySQL 的 table 時(shí),當(dāng)然她也是需要 open/close table 的,但是 它并不是每次都去 open/close table, 因?yàn)樗鼤?huì)將以前訪問(wèn)過(guò)的 table 保存下來(lái)以供來(lái)是使用,而 opening/closing tables 是最耗資源的,而且很容易引起互斥量的爭(zhēng)奪,這樣一來(lái),對(duì)于提高性能,非常有效。在流量變小時(shí), HandlerSocket 會(huì) close tables, 所以,它不會(huì)阻塞 administrative commands (DDL).

          它與MySQL + Memcached 的區(qū)別在哪呢? 對(duì)比圖1 和圖2 ,可從中看出其不同點(diǎn)。圖2 展示了典型的 MySQL + Memecached 的使用. 因?yàn)?Memcached 的 get 操作比 MySQL 的內(nèi)存中/磁盤(pán)上的主鍵查詢(xún)要快很多,所以 Memcached 用于緩存數(shù)據(jù)庫(kù)記錄。如果 HandlerSocket 的查詢(xún)速度能和 Memcached 媲美,我們就不需要使用 Memcached 來(lái)緩存記錄。

          

          舉一個(gè)例子,假設(shè)有一 user 表,通過(guò) user_id 來(lái)獲取用戶(hù)信息:

        CREATE TABLE user
        (
        user_id INT UNSIGNED PRIMARY KEY,
        user_name VARCHAR(50),
        user_email VARCHAR(255),
        created DATETIME
        )
        ENGINE=InnoDB;
        

          用 SELECT 語(yǔ)句獲取用戶(hù)信息

        mysql> SELECT user_name, user_email, created FROM user WHERE user_id=101;
        +---------------+-----------------------+---------------------+
        | user_name | user_email | created
        | +---------------+-----------------------+---------------------+
        | Yukari Takeba | yukari.takeba@dena.jp | 2010-02-03 11:22:33
        | +---------------+-----------------------+---------------------+
        1 row in set (0.00 sec)
        

          下面我們來(lái)看看如何使用 HandlerSocket 完成同樣的事情.

        安裝 HandlerSocket

          HandlerSocket具體安裝步驟請(qǐng)參考這里,基本步驟如下:

        1 下載HandlerSocket
        2 編譯 HandlerSocket(客戶(hù)端和服務(wù)端)
        [root@localhost handlersocket]# ./configure --with-mysql-source=mysql-source-dir --with-mysql-bindir=mysql-server-bin-dir
        [root@localhost handlersocket]# make
        [root@localhost handlersocket]# make install
        
        3 安裝 HandlerSocket
        mysql> INSTALL PLUGIN \'handlersocket\' soname \'handlersocket.so\';
        

          因?yàn)?HandlerSocket是 MySQL 插件,所以可以象使用其它插件,如 InnoDB, Q4M 和 Spider 那樣使用它,即不需要修改 MySQL 源代碼,MySQL 最好是 5.1 或更高版本,編譯 HandlerSocket 時(shí)需要 MySQL 源碼和 MySQL 庫(kù)。

        書(shū)寫(xiě) HandlerSocket 客戶(hù)端代碼

          目前已提供 C++ 和 perl 調(diào)用的客戶(hù)端庫(kù),下面是使用 perl 調(diào)用的實(shí)例代碼:

        #!/usr/bin/perl 
        
        use strict;
        use warnings;
        use Net::HandlerSocket; 
        
        #1. establishing a connection
        my $args = { host => \'ip_to_remote_host\', port => 9998 };
        my $hs = new Net::HandlerSocket($args); 
        
        #2. initializing an index so that we can use in main logics.
        # MySQL tables will be opened here (if not opened)
        my $res = $hs->open_index(0, \'test\', \'user\', \'PRIMARY\',
         \'user_name,user_email,created\');
        die $hs->get_error() if $res != 0; 
        
        #3. main logic
        #fetching rows by id
        #execute_single (index id, cond, cond value, max rows, offset)
        $res = $hs->execute_single(0, \'=\', [ \'101\' ], 1, 0);
        die $hs->get_error() if $res->[0] != 0;
        shift(@$res);
        for (my $row = 0; $row < 1; ++$row) {
         my $user_name= $res->[$row + 0];
         my $user_email= $res->[$row + 1];
         my $created= $res->[$row + 2];
         print "$user_name\\t$user_email\\t$created\\n";
        } 
        
        #4. closing the connection
        $hs->close()
        
        #!/usr/bin/perl 
        
        use strict;
        use warnings;
        use Net::HandlerSocket; 
        
        #1. establishing a connection
        my $args = { host => \'ip_to_remote_host\', port => 9998 };
        my $hs = new Net::HandlerSocket($args); 
        
        #2. initializing an index so that we can use in main logics.
        # MySQL tables will be opened here (if not opened)
        my $res = $hs->open_index(0, \'test\', \'user\', \'PRIMARY\',
         \'user_name,user_email,created\');
        die $hs->get_error() if $res != 0; 
        
        #3. main logic
        #fetching rows by id
        #execute_single (index id, cond, cond value, max rows, offset)
        $res = $hs->execute_single(0, \'=\', [ \'101\' ], 1, 0);
        die $hs->get_error() if $res->[0] != 0;
        shift(@$res);
        for (my $row = 0; $row < 1; ++$row) {
         my $user_name= $res->[$row + 0];
         my $user_email= $res->[$row + 1];
         my $created= $res->[$row + 2];
         print "$user_name\\t$user_email\\t$created\\n";
        } 
        
        #4. closing the connection
        $hs->close();
        

          上面代碼是通過(guò) user_id=101 條件在 user 表獲取用戶(hù) user_name, user_email和 created 信息,得到的結(jié)果應(yīng)該和之前在 MySQL client 查詢(xún)出來(lái)的結(jié)果一樣。

        [matsunobu@host ~]$ perl sample.pl
        Yukari Takeba yukari.takeba@dena.jp 2010-02-03 11:22:33
        

          對(duì)于大多數(shù)Web應(yīng)用程序而言,保持輕量級(jí)的 HandlerSocket 連接是一個(gè)很好的做法(持續(xù)連接),讓大量的請(qǐng)求可以集中于主要邏輯(上面代碼中的#3部分)。

           HandlerSocket 協(xié)議是一個(gè)小尺寸的基于文本的協(xié)議,和 Memcached 文本協(xié)議類(lèi)似,可以使用 telnet 通過(guò) HandlerSocket 獲取數(shù)據(jù)。

        [matsunobu@host ~]$ telnet 192.168.1.2 9998
        Trying 192.168.1.2...
        Connected to xxx.dena.jp (192.168.1.2).
        Escape character is \'^]\'.
        P 0 test user PRIMARY user_name,user_email,created
        0 1
        0 = 1 101
        0 3 Yukari Takeba yukari.takeba@dena.jp 2010-02-03 11:22:33
        (Green lines are request packets, fields must be separated by TAB)
        

          綠色表示請(qǐng)求數(shù)據(jù)包,字段必須用Tab鍵分隔。

          現(xiàn)在是時(shí)候展示基準(zhǔn)測(cè)試結(jié)果,使用上面的 user 表,從多線程遠(yuǎn)程客戶(hù)端測(cè)試了執(zhí)行主鍵查詢(xún)操作的次數(shù),所有用戶(hù)數(shù)據(jù)都裝入到內(nèi)存中(我測(cè)試了 100 萬(wàn)行),也用類(lèi)似的數(shù)據(jù)測(cè)試了 Memcached(我使用 libMemcached 和 Memcached_get() 獲取用戶(hù)數(shù)據(jù)),在 MySQL SQL 測(cè)試中,我使用了的是傳統(tǒng)的 SELECT 語(yǔ)句: “SELECT user_name, user_email, created FROM user WHERE user_id=?”, Memcached 和 HandlerSocket 客戶(hù)端代碼均使用 C/C++ 編寫(xiě),所有客戶(hù)端程序都位于遠(yuǎn)程主機(jī)上,通過(guò) TCP/IP 連接到 MySQL/Memcached。最高的吞吐量情況如下:

         approx qps server CPU util
        MySQL via SQL 105,000 %us 60% %sy 28%
        Memcached 420,000 %us 8% %sy 88%
        MySQL via HandlerSocket 750,000 %us 45% %sy 53%
        

          HandlerSocket的吞吐量比使用傳統(tǒng) SQL 時(shí)高出 7.5, 而且 %us 也只有使用傳統(tǒng) SQL 時(shí)的3/4, 這說(shuō)明 MySQL 的 SQL 層是非常耗資源的,如果能跳過(guò)這一層,性能肯定會(huì)大大提升。有趣的是,MySQL 使用 HandlerSocket 時(shí)的速度比使用 Memcached 也要快 178%,并且 Memcached 消耗的 %sy 資源也更多。所以雖然 Memcached 是一個(gè)很好的產(chǎn)品,但仍然有優(yōu)化的空間。

          下面是oprofile輸出內(nèi)容,是在 MySQL HandlerSocket 測(cè)試期間收集到的,在核心操作,如網(wǎng)絡(luò)數(shù)據(jù)包處理,獲取數(shù)據(jù)等的 CPU 資源消耗(bnx2是一個(gè)網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序)。

        samples % app name symbol name
        984785 5.9118 bnx2 /bnx2
        847486 5.0876 ha_innodb_plugin.so.0.0.0 ut_delay
        545303 3.2735 ha_innodb_plugin.so.0.0.0 btr_search_guess_on_hash
        317570 1.9064 ha_innodb_plugin.so.0.0.0 row_search_for_mysql
        298271 1.7906 vmlinux tcp_ack
        291739 1.7513 libc-2.5.so vfprintf
        264704 1.5891 vmlinux .text.super_90_sync 
        
        248546 1.4921 vmlinux blk_recount_segments
        244474 1.4676 libc-2.5.so _int_malloc
        226738 1.3611 ha_innodb_plugin.so.0.0.0 _ZL14build_template P19row_prebuilt_structP3THDP8st_tablej
        206057 1.2370 HandlerSocket.so dena::hstcpsvr_worker::run_one_ep()
        183330 1.1006 ha_innodb_plugin.so.0.0.0 mutex_spin_wait
        175738 1.0550 HandlerSocket.so dena::dbcontext:: cmd_find_internal(dena::dbcallback_i&, dena::prep_stmt const&, ha_rkey_function, dena::cmd_exec_args const&)
        169967 1.0203 ha_innodb_plugin.so.0.0.0 buf_page_get_known_nowait
        165337 0.9925 libc-2.5.so memcpy
        149611 0.8981 ha_innodb_plugin.so.0.0.0 row_sel_store_mysql_rec
        148967 0.8943 vmlinux generic_make_request
        

          因?yàn)?HandlerSocket 是運(yùn)行于 MySQL 內(nèi)部,直接與 InnoDB 交互,所以,可以使用常見(jiàn)的 SQL 命令,如 SHOW GLOBAL STATUS 獲得統(tǒng)計(jì)信息,Innodb_rows_read 達(dá)到了 750000+ 是值得一看的。

        $ mysqladmin extended-status -uroot -i 1 -r | grep "InnoDB_rows_read"
        ...
        | Innodb_rows_read | 750192 |
        | Innodb_rows_read | 751510 |
        | Innodb_rows_read | 757558 |
        | Innodb_rows_read | 747060 |
        | Innodb_rows_read | 748474 |
        | Innodb_rows_read | 759344 |
        | Innodb_rows_read | 753081 |
        | Innodb_rows_read | 754375 |
        ...
        

          測(cè)試用機(jī)的詳細(xì)信息如下:

        型號(hào) 戴爾PowerEdge R710
        CPU Nehalem 8核,E5540@2.53GHz
        內(nèi)存 32GB(所有數(shù)據(jù)都裝入緩沖池)
        MySQL 5.1.50 InnoDB
        Memcached/libMemcached 1.4.5(Memcached),0.44(libMemcached)
        Network Boradcom NetXtreme II BCM5709 1000Base-T(內(nèi)建四端口,使用了其中三個(gè))

          Memcached 和 HandlerSocket 都做了網(wǎng)絡(luò) I/O 限制,當(dāng)我測(cè)試單個(gè)端口時(shí),HandlerSocket 的 QPS 為 260000,而 Memcached 為 220000。 

          如下所述,HandlerSocket 有其自己的特點(diǎn)和優(yōu)勢(shì),而其中一些對(duì)我們來(lái)說(shuō), 是真的很給力.

        支持多種查詢(xún)模式

          HandlerSocket 目前支持 主鍵/唯一性查詢(xún),非唯一性索引查詢(xún),范圍掃描,LIMIT 和 INSERT/UPDATE/DELETE,但還不支持未使用任何索引的操作。另外,multi_get()(類(lèi)似于in(1,2,3), 只需一次網(wǎng)絡(luò)往返)還可獲取多行數(shù)據(jù)。到這里可查詢(xún)?cè)敿?xì)信息。

        處理大量并發(fā)連接

          HandlerSocket 連接是輕量級(jí)的,因?yàn)?HandlerSocket 采用epoll()和 worker-thread/thread-pooling 架構(gòu),而 MySQL 內(nèi)部線程的數(shù)量是有限的(可以由 my.cnf中的 handlersocket_threads參數(shù)控制),所以即使建立上千萬(wàn)的網(wǎng)絡(luò)連接到 HandlerSocket,它的穩(wěn)定性也不會(huì)受到任何影響(消耗太多的內(nèi)存,會(huì)造成巨大的互斥競(jìng)爭(zhēng)等其他問(wèn)題,如bug#26590,bug#33948,bug#49169)。

        及其優(yōu)秀的性能

          HandlerSocket,如上所描述, 相對(duì)于其它 NoSQL 陣容,性能表現(xiàn)一點(diǎn)也不遜色。事實(shí)上,我還未曾見(jiàn)過(guò)哪個(gè) NoSQL 產(chǎn)品在一臺(tái)普通服務(wù)器上可達(dá)到 750000+ 次查詢(xún)。它不僅沒(méi)有調(diào)用與 SQL 相關(guān)的函數(shù),還優(yōu)化了網(wǎng)絡(luò)/并發(fā)相關(guān)的問(wèn)題。

        更小的網(wǎng)絡(luò)數(shù)據(jù)包

           和傳統(tǒng) MySQL 協(xié)議相比,HandlerSocket 協(xié)議更簡(jiǎn)短,因此整個(gè)網(wǎng)絡(luò)的流量更小。

        運(yùn)行有限的 MySQL 內(nèi)部線程數(shù)

           參考上面的內(nèi)容。

        將客戶(hù)端請(qǐng)求分組

           當(dāng)大量的并發(fā)請(qǐng)求抵達(dá) HandlerSocket 時(shí),每個(gè)工作線程盡可能多地聚集請(qǐng)求,然后同時(shí)執(zhí)行聚集起來(lái)的請(qǐng)求和返回結(jié)果。這樣,通過(guò)犧牲一點(diǎn)響應(yīng)時(shí)間,而大大地提高性能。例如,你可以得到以下好處,如果有人感興趣,我會(huì)在今后的文章中對(duì)它們加以深入的解釋。

           減少fsync()調(diào)用的次數(shù).

           減少?gòu)?fù)制延遲.

        無(wú)重復(fù)緩存

          當(dāng)使用 Memcached 緩存 MySQL/InnoDB 記錄時(shí),在 Memcached 和 InnoD B緩沖池中均緩存了這些記錄,因此效率非常低(內(nèi)存仍然很貴). 而采用 HandlerSocket插件, 由于它訪問(wèn) InnoDB 存儲(chǔ)引擎,記錄緩存在 InnoDB 緩沖池中,這樣,其它 SQL 語(yǔ)句就可以重復(fù)使用它。

        無(wú)數(shù)據(jù)不一致的現(xiàn)象

          由于數(shù)據(jù)只存儲(chǔ)在一個(gè)地方(InnoDB 內(nèi)),不像使用 Memcached 時(shí),需要在 Memcached 和 MySQL 之間檢查數(shù)據(jù)一致性。

        崩潰安全

          后端存儲(chǔ)是 InnoDB,它是事務(wù)性和崩潰安全的,即使有設(shè)置innodb-flush-log-at-trx-commit!=1,在服務(wù)器崩潰時(shí)也只會(huì)丟掉 < 1s 內(nèi)的數(shù)據(jù)。

        可從 MySQL 客戶(hù)端使用 SQL

          在許多情況下,人們?nèi)匀幌M褂?SQL(如生產(chǎn)摘要報(bào)告),這就是為什么我們不能使用嵌入式 InnoDB 的原因,大多數(shù) NoSQL 產(chǎn)品都不支持 SQL 接口,HandlerSocket 僅僅是一個(gè) MySQL 插件,可以從 MySQL 客戶(hù)端發(fā)送 SQL 語(yǔ)句,但當(dāng)需要高吞吐量時(shí),最好使用 HandlerSocket。

        從 MySQL獲益

          因?yàn)?HandlerSocket 運(yùn)行于 MySQL 內(nèi)部,因此所有 MySQL 操作,如 SQL,在線備份,復(fù)制,通過(guò) Nagios/EnterpriseMonitor 監(jiān)控等都是支持的,HandlerSocket 獲得可以通過(guò)普通的 MySQL 命令監(jiān)控,如SHOW GLOBAL STAUTS,SHOW ENGINE INNODB STATUS和SHOW PROCESSLIST等.

        不需要修改/重建 MySQL

          因?yàn)?HandlerSocket 是一個(gè)插件,所以它支持 MySQL 社區(qū)版和企業(yè)服務(wù)器版,而無(wú)需對(duì) MySQL 做出任何修改就可以使用。

        獨(dú)立于存儲(chǔ)引擎

          雖然我們只測(cè)試了5.1和5.5 InnoDB 插件,但 HandlerSocket 可以和任何存儲(chǔ)引擎交互。

        需要學(xué)習(xí)HandlerSocket API

          盡管它很容易使用,但仍然需要學(xué)習(xí)如何與 HandlerSocket 交互,我們提供了C++ API、Perl綁定。

        沒(méi)有安全功能

          和其它NoSQL數(shù)據(jù)庫(kù)類(lèi)似,HandlerSocket不支持安全功能,HandlerSocket的工作線程以系統(tǒng)用戶(hù)權(quán)限運(yùn)行,因此應(yīng)用程序可以訪問(wèn)通過(guò) HandlerSocket 協(xié)議的所有表,當(dāng)然,你可以象其它 NoSQL 產(chǎn)品一樣使用防火墻過(guò)濾數(shù)據(jù)包。

        對(duì)于 HDD 綁定工作負(fù)載沒(méi)有優(yōu)勢(shì)

          對(duì)于 HDD I/O 綁定工作負(fù)載,數(shù)據(jù)庫(kù)每秒無(wú)法執(zhí)行數(shù)千次查詢(xún),通常只有 1-10% 的 CPU 利用率,在這種情況下,SQL 執(zhí)行層不會(huì)成為瓶頸,因此使用HandlerSocket沒(méi)有什么優(yōu)勢(shì),我們只在數(shù)據(jù)完全裝載到內(nèi)存的服務(wù)器上使用 HandlerSocket。

          我們已經(jīng)在生產(chǎn)環(huán)境中使用了 HandlerSocket 插件,效果很明顯,因?yàn)槲覀儨p少了許多 Memcached 和 MySQL 從屬服務(wù)器,而且整個(gè)網(wǎng)絡(luò)流量也在減少。目前還沒(méi)有發(fā)現(xiàn)任何性能問(wèn)題(如響應(yīng)時(shí)間慢,延遲等)。

           我認(rèn)為, NoSQL/Database 社區(qū)完全低估了 MySQL, 相對(duì)于其他產(chǎn)品來(lái)說(shuō),它歷史悠久,而且到目前為止,我優(yōu)秀的前同事們也做了許多獨(dú)特的、偉大的改進(jìn)。從 NDBAPI 可以看出 MySQL 有成為 NoSQL 的潛力,因?yàn)榇鎯?chǔ)引擎 API 和守護(hù)進(jìn)程接口的完全獨(dú)立,使得 Akira 和 DeNA 開(kāi)發(fā) HandlerSocket 成為可能。作為 MySQL 一名前員工和對(duì) MySQL 長(zhǎng)期的了解,我想看到 MySQL 變得更好,更受歡迎,而不僅僅只作為一個(gè) RDBMS,也應(yīng)該成為 NoSQL 陣營(yíng)中的一員。

        聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        UsingMySQLasaNoSQL_MySQL

        UsingMySQLasaNoSQL_MySQL:NoSQL FROM: Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server 由于 MySQL 的局限性,很多站點(diǎn)都采用了 MySQL+Memcached 的架構(gòu)。另外一些站點(diǎn)放棄 MySQL 而采用 NoSQL,比如 TokyoCa
        推薦度:
        標(biāo)簽: sql mysql nosql
        • 熱門(mén)焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門(mén)推薦

        專(zhuān)題
        Top
        主站蜘蛛池模板: 歪歪漫画在线观看官网免费阅读| 免费国产黄网站在线观看视频| 在线精品一卡乱码免费| 亚洲开心婷婷中文字幕| 日本高清不卡中文字幕免费| 亚洲美女又黄又爽在线观看| 亚洲AV第一成肉网| 最新中文字幕电影免费观看| 亚洲av极品无码专区在线观看| 亚洲精品伦理熟女国产一区二区| 亚洲AV无码一区二区三区网址| 国产桃色在线成免费视频| 亚洲国产精品13p| 美女视频黄a视频全免费网站色| 日韩高清在线免费看| 亚洲经典千人经典日产| 日本免费人成黄页网观看视频 | 亚洲人成电影院在线观看| 亚洲AV成人精品一区二区三区| 色窝窝免费一区二区三区| 亚洲自偷自偷在线成人网站传媒 | 亚洲免费无码在线| 四虎在线免费视频| JLZZJLZZ亚洲乱熟无码| 亚洲乱码无限2021芒果| 黄瓜视频影院在线观看免费| 亚洲同性男gay网站在线观看| 免费无码又黄又爽又刺激| 亚洲日本在线电影| 亚洲国产精品激情在线观看| 美女网站在线观看视频免费的 | 亚洲电影在线免费观看| 亚洲精品97久久中文字幕无码| 粉色视频在线观看www免费| 中文字幕久久亚洲一区| 四虎影视在线影院在线观看免费视频 | 亚欧乱色国产精品免费视频| 精品亚洲成α人无码成α在线观看 | 亚洲国产成人精品无码一区二区 | 日本视频免费在线| 丁香六月婷婷精品免费观看|