Home » 2013 » October

十個改善 MySQL 效能的方式

Zite 上看到這篇介紹 MySQL 效能調教的方式:「Ten ways to improve the performance of large tables in MySQL」。

這邊就順著作者的建議一路寫下去。

作者也是大力推薦用 InnoDB 解決問題。

InnoDB 有個特別的功能 (相較於 MyISAM 而言。這個功能在 MySQL 5.5 預設就是開啟的) 是 change buffering,會延遲寫入 non-unique secondary index,讓多筆 secondary index 合併起來一起寫,這會改善寫入的效能。

Partition 對於 index 的大小也會有幫助。InnoDB 的壓縮功能也是必備項目 (除非你的 Use case 很極端),減少資料量就直接減少 i/o 並且拉高 hitrate。

再大量寫入資料時依照順序寫入會讓 InnoDB 寫入的順序僅可能連續。由於 InnoDB 的特性 (clustered index),這樣可以讓寫入速度變快很多。

避免使用 UNIQUE key,因為 UNIQUE 的特性會犧牲很多效能...

因為 secondary index 是指到 PRIMARY KEY 的值,所以 PRIMARY KEY 的值僅可能單純,以 INT 或是 BIGINT 為佳。

第一次大量倒資料進系統時,可以先倒 data 以及 PRIMARY KEY 就好 (如上所說的,要依照 PRIMARY KEY 的順序倒進去),等倒完後再建立 secondary index,這樣速度會快很多。

最後兩項就是,記憶體愈大愈好,硬碟愈快愈好,如果用 SSD 是可行的方案就用 :p

php.net 被擋的後續分析...

昨天一整天 php.net 網域下的網站都被擋掉:

Twitter 上也有看到 Rasmus Lerdorf 在抱怨:

Rasmus 說是 false positive (誤判),不過我是不太直接相信他講的話...

剛剛看到 Netcraft 整理了一些資料出來「PHP.net blocked by Google: False positive or not?」,裡面有不少東西可以看...

其中最後這段:

However, a short moment ago, a Hacker News user posted some obfuscated JavaScript that was found appended to a possibly cached version of the userprefs.js script, suggesting that the PHP.net website may have been compromised recently.

The obfuscated JavaScript inserts an iframe into the webpage, which loads content from an external site known for distributing malware. Google Chrome blocks the inclusion of any content from known malware domains, although the injected content in this case no longer appears to be accessible.

這段有問題的 javascript code 的解讀可以在這裡看到說明。

如果的確是 compromise,那這事就沒完了,接下來還要找是從哪個洞進來的... 不過以 php.net 的情況,(消音)...

Percona 的 MySQL High Availability 機制比較文

Percona 發了一篇「High-availability options for MySQL, October 2013 update」,比較目前 MySQL 上常見的 High Availability 機制。

包括了五個系統:

  • Percona XtraDB Cluster (PXC)
  • Percona replication manager (PRM)
  • MySQL master HA (MHA)
  • NDB Cluster
  • Shared storage/DRBD

這些都是把 High Availability 做在 MySQL 上,讓前端的程式不需要操心的方式。都是有個固定的 IP address 保證可以讀寫。

這五個方案都不完美,看環境需求而選擇使用。

我一般給的建議還是 Heartbeat + DRBD + InnoDB,這個方法是極為成熟的方法,會遇到的問題網路上都已經討論過了。如果找 Percona 的人支援也是完全沒問題。

AWS Direct Connect 向下提供 50Mbps 的連線頻寬...

在「AWS Direct Connect - More Connection Speeds, New Console, Multiple Accounts」這篇文章裡面提到了 AWS Direct Connect 可以接受 50Mbps~500Mbps 的頻寬了,而先前只接受 1Gbps 與 10Gbps...

不過 500Mbps 的頻寬與 1Gbps 頻寬的 port 價錢是相同的,都是 USD$0.3/hour,其他較低的速度就依照 500Mbps 的比率計算。

比較特別的是 50Mbps,是用 QoS 限制頻寬嗎?這樣的速度還蠻特別的...

氣象統計:MeteoTester

看到「MeteoTester collects and tests the accuracy weather APIs」這篇文章介紹 MeteoTester 這個站,拿來統計氣象誤差值...

about 頁面上有說明是統計 forecast.ioopenweathermap.orgwunderground.com 以及 worldweatheronline.com 這四個站的資料。

拉出來的圖像是這樣:

紅色是最高溫度,藍色是最低溫度,另外長條部份是降雨機率,然後三個值每個都有 range...

不過不知道這個資料可以做什麼... @_@

用 InnoDB 時關於 PRIMARY KEY 的建議

Percona 的「InnoDB scalability issues due to tables without primary keys」這篇文章在討論 InnoDB 在沒有 PRIMARY KEY 時的效能問題。

在討論效能問題前,應該先讀過 MySQL 官方文件裡提到 InnoDB index 架構的文章,其中就有提到 PRIMARY KEY 以及其他的 INDEX KEY 的底層架構:「InnoDB Table and Index Structures」。

InnoDB 是 clustered index 架構 (關於 clustered index 的完整說明,可以參考維基百科的「Database index」條目),也就是說,資料本身 (row data) 存放時會按照某個順序存放,這邊的順序是按照這樣的方式定義的:

  • 如果你有指定 PRIMARY KEY,那麼就會直接用 PRIMARY KEY 當作 clustered index。
  • 如果沒有指定 PRIMARY KEY,但有 UNIQUE INDEX,而且所有欄位都是 NOT NULL,那麼就用這組 UNIQUE INDEX (NOT NULL) 當作 clustered index。
  • 如果都沒有指定 PRIMARY KEY,那麼就會產生一個隱藏的欄位,是一個 6 bytes 的 auto increment 的數字,用這個欄位當 clustered index。也因為如此,在這種情況下,資料會依照建立的順序存放。

另外,InnoDB 的 secondary index 會指到 PRIMARY KEY (B+Tree 的 value 部分是放 PRIMARY KEY)。

所以,一般在規劃資料庫時建議的作法是:

  • 所有的表格都要有 PRIMARY KEY。
  • PRIMARY KEY 必須是 INT UNSIGNED (4 bytes),只有在需要 BIGINT UNSIGNED (8 bytes)的時候才用 BIGINT UNSIGNED。

對於有大量 secondary index 的表格更應該這樣做 (因為可以省下大量空間)。而對於現代的 ORM 來說,也都幾乎要求要有 PRIMARY KEY,甚至有些 ORM 要求 PRIMARY KEY 必須是 single column。

如果你都能了解後,再去看 Percona 討論沒有 PRIMARY KEY 的情況時,才能了解他們想要討論什麼事情... 裡面還包含了 InnoDB 格式的差異。

Archives