MySQL 上的 Thread Pool...

Percona 的人寫了一篇「Percona Server: Improve Scalability with Percona Thread Pool」,提到關於 MySQL 在連線數很多時的效能。

傳統的作法是一個連線使用一個 thread,這種方法實做起來很簡單,但當連線數超過一定程度時就會因為共用資源的限制而變慢。

其中一種解決方法是引入 Thread Pool 架構,也就是 M 個 thread 處理 N 個連線。

Oracle 有提供商用版本叫做 Thread Pool Plugin,就如同名字,是以 plugin 形式存在。這個功能在 5.55.6 都有。

MariaDB 也有 open source 實做的 Thread pool

而 Percona 則是使用 MariaDB 的版本。(原文是說有改善,不過 benchmark 並沒有列出來,我「猜」其實沒什麼改善...)

可以看到在多連線數時的效果相當好。在 MariaDB 的文件裡有提到會有改善的時機:

Threadpools are most efficient in situations where queries are relatively short and the load is CPU bound (OLTP workloads). If the workload is not CPU bound, you might still want to limit the number of threads to save memory for the database memory buffers.

query 相對短,而且是 CPU bound。

回頭看的時候發現 Percona Server 5.5 就有支援 Thread Pool 了,應該來測試看看效果如何...

MySQL 平行執行的 Replication...

MySQL Replication – Multi-Threaded Slaves (Parallel Event Execution)」這篇在講 MySQL 5.6 的 multi-threaded replication。

在文章裡提到,在 5.6.3 之前的版本,MySQL replication 都是 single-threaded,所以當 master 可以充分發揮多 CPU 能力時,slave 仍然要一個更新跑完才會跑下一個更新。

舉例來說,假設 master server 上有兩個 thread 在跑:

  • thread 1 正在執行 UPDATE table1 SET foo = 0 WHERE ...; (SQL 1,假定是 CPU bound,需要跑 100 秒)
  • thread 2 正在執行 UPDATE table2 SET bar = 1 WHERE ...; (SQL 2,也假定是 CPU bound,也需要跑 100 秒)

假設 thread 1 先執行完,這時候 slave 就會在跑完的時候收到 SQL 1,然後把資料同步進去。等到 100 秒過去後,再跑 SQL 2,再花 100 秒。這導致了最少 100 秒的 replication lag (master 與 slave 不同步的時間)。

在 master server 執行時會是這樣:

兩個 SQL query 可以同時跑。

到了 slave 時,在 MySQL 5.6.3 之前的 replication 會變成這樣:

可以看到還是得先執行 SQL 1 再執行 SQL 2,所以最長會有 200 秒的 replication lag。

而 5.6.3 之後支援 multi-threaded replication,可以用 slave_parallel_workers 指定平行執行 SQL query 的數量,這讓 master server 與 slave server 之間的 replication lag 降低不少:

在收到同步的 SQL 指令後就可以同時跑,這讓 replication lag 降到 100 秒。

不過還是要提,如果希望把資料同步問題降到最低,那麼 Galera Cluster 可以解的更徹底,不論是寫入的那台 master server,或是其他的 master server (在 Galera Cluster 架構裡都是為 master),一律都是同步執行:

不會有 master server 與 slave server 不同步的問題,可以減少很多 application 層的麻煩...

用 Lbzip2 解壓縮

手上抓了幾個 .bz2 的檔案要 bzcat 出來 pipe 丟給 Perl script 跑,用系統預設的 bzip2 發現速度卡在解壓縮,而不是 Perl script...

用 parallel 與 bzip2 當關鍵字到 apt-cache 裡面找,有找到兩個套件:Lbzip2Pbzip2,都裝起來後測解壓縮的功能,發現 Pbzip2 解壓縮時沒有辦法利用到多核心的優勢,而 Lbzip2 則是很順利的超過 100%,輸出結果讓 Perl script 也吃滿 CPU resource...

如果是壓縮時需要壓縮率,還是用 xz 就好...

裝 mplayer-mt 改善解碼效率

用 multi-threaded 版本可以將解碼的程式丟到多顆 CPU core 上跑,善用多 CPU 的資源,這樣看 1080p 才不會痛... (家裡的 AMD X2 4000+ 得這樣設,不然原來的版本解不動)

主要有兩個步驟要做,首先是加 ppa 並且安裝 mplayer-mt:

sudo apt-add-repository ppa:longinus00/mplayer-mt
sudo apt-get update
sudo apt-get upgrade # 已經有 mplayer 的 case
sudo apt-get install mplayer # 沒有裝 mplayer 的 case

然後是設定 smplayer 要他在用 mplayer 時加上參數: 參數是「-lavdopts threads=4」。

不過寫完才發現我這張 video card 有硬解可以用... XD

Perl 的 Threading 實做:Coro

去年「Perl - PSGI」這篇文章裡面提到 Perl 的 threading 一直是頭痛的問題之一,唐鳳在留言上推薦用 Coro 而非原來的 thread。

實際測試後發現並非 OS level 的 threading,而是利用抽換的方式將系統內許多 blocking function 換掉,並且支援常用到的 module (像是 libwww-perl 系列),使得現有的程式要 porting 到 Coro 上會簡單很多,寫起來也的確比較像 threading 程式。(雖然實做比較接近 event-based)

附上之前寫來測試的程式,用的是 PIXNETAPI