Amazon Redshift 支援 Zstandard

Amazon Redshift 支援 Zstandard 壓縮資料:「Amazon Redshift now supports the Zstandard high data compression encoding and two new aggregate functions」。

Zstandard 是 Facebook 的人發展出來的壓縮與解壓縮方式,對比的對象主要是 zlib (或者說 gzip),官網上有不少比較圖。目標是希望在同樣的壓縮處理速度下,可以得到更好的壓縮率。

Redshift 支援 Zstandard 等於是讓現有使用 gzip 的使用者免費升級的感覺...

細看 MySQL 的 Performance Schema 對效能的影響

Percona 的人對 MySQL 5.7 的 OLTP RW 測試中,Performance Schema 的各種不同的功能對效能帶來的影響:「Performance Schema Benchmarks: OLTP RW」。

原文章裡有定義這些分別是打開哪些功能,這邊就跳過去... 重點是 default 值對效能的影響其實不算高,所以除非是想要壓榨每一分效能,不然其實可以考慮打開 (針對 OLTP RW 類似的應用):

影響比較大的是 Stages 與 Waits 的部份。而 Mark Callaghan 在 comment 提到在 Performance Schema Event Timing 這邊有相關的資料... 看起來應該可以降低對 Stages 與 Waits 的效能衝擊。

MyRocks 與 InnoDB 在 INSERT 效能的比較

MyRocksMark Callaghan 對 INSERT 效率整理出來的比較:「Insert benchmark, MyRocks and InnoDB」。

當資料比記憶體小的時候,InnoDB 效能比較好。但超過記憶體大小時就是 MyRocks 效能比較好。另外 InnoDB 在 MySQL 5.7 的效率比 5.6 好不少。

兩張圖來自相同資料,只是 x 軸不太一樣。

是從 16 台 client 裡面抽一台的量出來,這樣就可以解釋後面那段爬上來... (其他台跑完了,所以這台的 insert 速度變快了)

This is for data from one of the 16 clients rather than the global rate because my test script forgot to collect that.

While it is odd that the throughput rate for InnoDB 5.7 picks up at test end, that can occur if the thread I monitored ran longer than other threads and had less competition for HW resources near test end.

Swap 對 InnoDB 的影響

Percona 的老大拿 5.7 版做實驗,確認 swap 對 InnoDB 的影響:「The Impact of Swapping on MySQL Performance」。

測試的機器是 32GB RAM,作業系統 (以及 swap) 裝在已經有點年紀的 Intel 520 SSD 上,而 MySQL 則是裝在 Intel 750 NVMe 上。透過對 innodb_buffer_pool 的調整來看情況。

可以看到設為 24GB (記憶體 75% 的量) 時很穩定的在 44K QPS 與 3.5ms (95%):

This gives us about 44K QPS. The 95% query response time (reported by sysbench) is about 3.5ms.

而當設成 32GB 的時候開始可以觀察到 swap i/o,掉到 20K QPS 與 9ms (95%):

We can see that performance stabilizes after a bit at around 20K QPS, with some 380MB/sec disk IO and 125MB/sec swap IO. The 95% query response time has grown to around 9ms.

當拉到 48GB 的時候就更掉更多,6K QPS 與 35ms (95%):

Now we have around 6K QPS. Disk IO has dropped to 250MB/sec, and swap IO is up to 190MB/sec. The 95% query response time is around 35ms.

作者發現掉的比率沒有想像中大:

When I started, I expected severe performance drop even with very minor swapping. I surprised myself by getting swap activity to more than 100MB/sec, with performance “only” halved.

這邊測試用的是 SSD,如果是傳統用磁頭的硬碟,對 random access 應該會很敏感而掉更多:

This assumes your swap space is on an SSD, of course! SSDs handle random IO (which is what paging activity usually is) much better than HDDs.

基本上還是要避免碰到 swap 啦,另外 comment 的地方剛好有提到前陣子在猜測的 best practice,測試時的 vm.swappiness 是設成 1,這應該是作者的 best practice:

Swappiness was set to 1 in this case. I was not expecting this to cause significant impact as swapping is caused by genuine (intended) missconfiguration with more memory required than available.

Amazon Aurora 支援 Auditing

AWS 的人把 auditing plugin 移植到 Amazon AuroraMySQL 環境上了:「Auditing an Amazon Aurora Cluster」。

官方宣稱的效能很好,打開後不會掉太多:

主要原因是把寫 auditing log 這塊改寫掉:

這樣看起來頗不錯,平常其實可以開起來讓他記錄?

GitHub 重新定位 Redis 的功能...

GitHub Engineering 說明了他們為什麼改變 Redis 的使用情境:「Moving persistent data out of Redis」。

GitHub 裡面,Redis 有兩種不同的情境,一種叫做 transient Redis,只用做 cache:

We used it as an LRU cache to conveniently store the results of expensive computations over data originally persisted in Git repositories or MySQL. We call this transient Redis.

另外一種則是打開 persistence 功能,叫做 persistent Redis:

We also enabled persistence, which gave us durability guarantees over data that was not stored anywhere else. We used it to store a wide range of values: from sparse data with high read/write ratios, like configuration settings, counters, or quality metrics, to very dynamic information powering core features like spam analysis. We call this persistent Redis.

這邊講的是 persistent Redis 被換成用 MySQL (InnoDB) 儲存:

Recently we made the decision to disable persistence in Redis and stop using it as a source of truth for our data. The main motivations behind this choice were to:

  • Reduce the operational cost of our persistence infrastructure by removing some of its complexity.
  • Take advantage of our expertise operating MySQL.
  • Gain some extra performance, by eliminating the I/O latency during the process of writing big changes on the server state to disk.

For the majority of callsites, we replaced persistent Redis with GitHub::KV, a MySQL key/value store of our own built atop InnoDB, with features like key expiration. We were able to use GitHub::KV almost identically as we used Redis: from trending repositories and users for the explore page, to rate limiting to spammy user detection.

後面講了不少轉換的過程 (還包含了某些功能的改寫),但沒有講的太清楚為什麼不繼續使用 Redis。

目前只能就提到的三點問題來看,persistent 的 i/o 成本可能太高?而且難以再壓榨效能出來?而相反的,InnoDB 已經花了很多力氣在上面,直接拿來用反而可以解決問題?

不過看得出來這個轉換還是花了不少力氣,看得出來有些 application 使用 Redis 的模式不能直接搬到 InnoDB 上,花了時間改寫...

vm.swappiness 設成 1 或是 0 的差異

在「MongoDB System Tuning Best Practices」這份投影片裡面看到:

To avoid disk-based swap: 1 (not zero!)

以及:

‘0’ can cause unpredicted behaviour

在 kernel 的說明文件是這樣描述,設成 0 時表示只有在避免 oom 時才會 swap:

This control is used to define how aggressive the kernel will swap memory pages. Higher values will increase agressiveness, lower values decrease the amount of swap. A value of 0 instructs the kernel not to initiate swap until the amount of free and file-backed pages is less than the high water mark in a zone.

設成 1 的想法頗有趣的,來看看在 MySQL 上是不是也有同樣的情況要注意...

MongoDB 的 replica-set 設定

Percona 的人寫了一份文件,以 MySQL DBA 的角度說明兩者在 replication 上的差異,然後示範怎麼在單機上架起三個 MongoDB 並且設定 replica-set:「First MongoDB replica-set Configuration for MySQL DBAs」。

這邊文章拿的是 Percona Server for MongoDB,不過應該也還行,並竟是拿 MongoDB 3.2 改的,而不是完全重寫,所以裡面的步驟拿到原版的 MongoDB 上應該也行...

可以拿 Docker 或是在 AWS 開一台 t2.medium 測試玩看看...

MySQL GTID Replication 的惡搞修復

Percona 的「Database Daily Ops Series: GTID Replication」這篇在講當 MySQL 的 GTID Replication 爛掉時可能的修法,算是頗惡搞的方法,修好後還是要跑 pt-table-checksum 確認兩邊的資料是否一致,如果有狀況的話還是得拿出 pt-table-sync 同步。

第一招是用 pt-slave-restart,跳過會造成問題 SQL,讓他強制同步 (唔):

This passes the master’s UUID and it skips all global transactions breaking replication on a specific slave server[.]

第二招是 mysqlslavetrx,也是類似的作法,只是拿的是 MySQL 官方的工具來惡搞...

第三招是 Inject a Fake Transaction,其實就是手動自己做 XDDD

所以不管是哪招,做完後還是要記得跑 pt-table-{checksum,sync} 收尾,不然還是會爛掉...