AWS Direct Connect 可以多條線路綁在一起用了

AWS Direct Connect 支援 Link Aggregation Group (LAG),將多條線路綁在一起了:「AWS Direct Connect enables Link Aggregation Group for additional AWS regions」。

We are excited to announce support for 1G and 10G Link Aggregation Groups (LAG). Customers in AWS GovCloud (US), Europe (Frankfurt), Europe (London), Europe (Ireland), Asia Pacific (Tokyo), Asia Pacific (Singapore), Asia Pacific (Sydney) regions can start using LAG to link existing connections on the same AWS device, or request new connections.

主要還是對於超大量的用戶會變方便 (都是使用 10Gbps 線路接上去的使用者),尤其是 load balancing 這塊會好做不少。

多條 1Gbps 的當然也是有幫助,不過剛好只會落在一個微妙的範圍 (到 8Gbps 的時候,直接換 10Gbps 成本說不定其實差不多...)。

Oracle 的人講 MySQL 5.7 最新出的 Group Replication

不愧是 Oracle 的 MySQL Community Manager,把對手的 Galera Cluster 講的一無是處 XDDD:「Group Replication is GA with MySQL 5.7.17 – comparison with Galera」。

然後下面 comment 的地方 Mark Callaghan (@Facebook) 出來提 Galera Cluster 架構中 arbitrator 的好處,另外 Sergei Petrunia (@MariaDB) 也出來糾正抹黑對手的 FUD (講 Galera Cluster 的 protocol 是 "proprietary"),不知道還會不會其他人跳進來...

另外文章裡面看起來也怪怪的,像是 Group Replication 在 InnoDB 上的作法真的能解決他說的問題嗎... conflict 把有問題的 transaction 砍掉不是很合理嗎?設計個 high priority transaction 是怎樣...

來繼續觀望看看就好,Galera Cluster 的成熟度還是很高的... 也許等到其他幾家也決定把 Group Replication 放進支援再說吧。

自適應演算法與 A/B Testing

Hacker News Daily 上看到三年前的舊文章,講自適應演算法取代常見的 A/B testing:「20 lines of code that will beat A/B testing every time」。

就拿原文裡面的例子來說明,我想要測試 "Buy Now!" 這個按鈕的顏色來得知哪個顏色的 click rate 最高,而我有 Orange、Green 以及 White 三種顏色為候選。

一開始我初始值都設為「展示了 1 次,被點擊了 1 次」,所以每個點擊率都是 100%:

Orange Green White
1/1 = 100% 1/1=100% 1/1=100%

然後你的網站上只要展示「點擊率最高的那個顏色」,並且記錄下來展示次數與點擊率就好,而整個過程會是自適應而被自動被淘汰掉,最後可能會變成這樣,就會固定是綠色的了:

Orange Green White
114/4071 = 2.8% 205/6385=3.2% 59/2264=2.6%

而這樣做的好處是節省人力成本:你不需要 A/B Testing 完後再人工介入修改。

對於更複雜的例子,雖然原文沒有提到,但你可以直接展開來做,舉例來說,你假設顏色與地區兩個變數所帶出來的 click rate 不是 i.i.d.,那麼你可以針對每個 Color + Region 都存數值去比較。

當然還是有他的問題 (comment 有提到),不過可以架出一些全自動的 workaround 來解決,比起要兩階段人工介入省了不少人力。

另外可以想像在大的產品上會遇到效能問題 (因為對同樣資料大量的 read + write),但這個數字不需要太即時,只要量大就會準確,所以技術上也可以解決...

Slack 的 User Groups 功能

Slack 最近除了推出了 Group Messages 以外 (參考「Slack 支援多人討論群組」),也推出了 User Groups 的功能給付費用戶使用:「Introducing User Groups」:

User Groups are enabled for all Slack teams on paid plans (both Standard and Plus). New groups can be created in the Team Directory panel in your desktop app. You can give each a descriptive name and add a note on purpose to help others understand what each group is for. The team directory will then list your team’s existing user groups and show the details of each, along with the the group’s members.

使用者可以被分類成 Group,然後可以針對某一個 Group 傳訊息。而 Plus Plan 的用戶可以透過 SSO 機制將群組資訊帶進來用:

For teams using Single Sign On (SSO) on the Plus plan, you can even use groups to control provisioning accounts from your SSO tools. Users of Active Directory in OneLogin, PingOne, PingFederate, or Okta can take advantage of this built-in user provisioning support to add employees automatically into Slack User Groups matching each employee’s existing group rights, roles and permissions in your internal directory.

另外也有提供 API 讓你用,所以 Standard Plan 用戶也可以自己寫,然後塞進去。

Slack 支援多人討論群組

Slack 宣佈支援多人討論群組了:「Group Messages Come to Slack」。之前要找一群人討論事情必須要開一個 Private Channel,但每次開 channel 都要想一個名字出來很討厭,後來都用 #test_201510290916 這種沒有意義的名字,而現在可以直接拉人進來了:

另外一個是跟著的改變:「Private Groups become Private Channels」。

With the introduction of group DMs, which will cover many of the use cases that previously required private groups, we’ve transformed private groups into the brand new “private channels”. Private channels will be shown mixed in with your existing open channels alphabetically, with small lock icons next to the private ones. When the time comes to create a new channel, you’ll find a new public/private toggle on the configuration screen.

原先的 Private Channel 就跟 Public Channel 混在一起了...

MySQL 在處理 GROUP BY 時選擇 index 的效率問題

Percona 的「Speed up GROUP BY queries with subselects in MySQL」這篇講了 MySQL 在處理 GROUP BY 的效率問題。

舉原文的例子,也就是這樣的 SQL query:(我把 command 都改成大寫,其他部份都改成小寫)

SELECT a.name, SUM(a.count) a_sum, AVG(a.position) a_avg, b.col1, c.col2, d.col3
FROM
a JOIN
b ON (a.bid = b.id) JOIN
c ON (a.cid = c.id) JOIN
d ON (a.did = d.id) GROUP BY a.name, b.id, c.id, d.id

其中 TABLE a 有 1.3M rows,而 b、c、d 都只有 5 rows。

由於會需要計算每組 (a.name, b.id, c.id, d.id)SUM(a.count)AVG(a.position),不可避免的是需要對 TABLE a 完整的掃一次。所以效能的改善會在於可以減少 temporily table 的大小。

上面這組 SQL query 會先 JOIN 完後再 GROUP BY,也就是會全部先展開後再 GROUP BY

由於 GROUP BY 所使用到的條件都可以在 TABLE a 裡面找到,所以這邊可以先 GROUP BY 後再 JOIN,降低 temporily table 的大小:

SELECT a.name, a_sum, a_avg, b.col1, c.col2, d.col3
FROM
(SELECT name, SUM(count) a_sum, AVG(position) a_avg, bid, cid, did
 FROM a
 GROUP BY name, bid, cid, did) a JOIN
 b ON (a.bid = b.id) JOIN
 c ON (a.cid = c.id) JOIN
 d ON (a.did = d.id)

原文測試出來的結果是從 2.3 秒降到 1.8 秒:

The first query took 2.3 sec avg and the optimized query took 1.8 sec average, half a second faster.

另外一個改善是再加上 covering index:

ALTER TABLE a ADD INDEX (name, bid, cid, did, count, position);

加上去之後,原來的 query 變成 1.9 秒,而改善後的變成 0.7 秒,速度快很多。不過這是 trade-off,多了這個 index 在寫入時的成本也會增加。

PostgreSQL 9.5 的 GROUPING SETS 以及 CUBE 與 ROLLUP

Zite 上看到的「Postgres finally has CUBE / ROLLUP / GROUPING SETS !」。

直接看 PostgreSQL 的文件「7.2.4. GROUPING SETS, CUBE, and ROLLUP」就可以知道用法:

=> SELECT * FROM items_sold;
 brand | size | sales
-------+------+-------
 Foo   | L    |  10
 Foo   | M    |  20
 Bar   | M    |  15
 Bar   | L    |  5
(4 rows)

=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());
 brand | size | sum
-------+------+-----
 Foo   |      |  30
 Bar   |      |  20
       | L    |  15
       | M    |  35
       |      |  50
(5 rows)

結果就是分次 GROUP BY 的聯集。而 CUBEROLLUP 則是提供列舉的方式。

ROLLUP 的部份:

ROLLUP ( e1, e2, e3, ... )

表示階層式的列舉:

GROUPING SETS (
    ( e1, e2, e3, ... ),
    ...
    ( e1, e2 )
    ( e1 )
    ( )
)

CUBE

CUBE ( a, b, c )

則是表示 power set (所有的組合):

GROUPING SETS (
    ( a, b, c ),
    ( a, b    ),
    ( a,    c ),
    ( a       ),
    (    b, c ),
    (    b    ),
    (       c ),
    (         ),
)

也有更複雜的 CUBE ( (a,b), (c,d) )GROUP BY a, CUBE(b,c), GROUPING SETS ((d), (e)) 可以用,參考文件裡的範例即可 :p

Group.NCTU.edu.tw (2003~2013)

2003 年寫的 Group.NCTU.edu.tw,在歷經 10 年後終於歸西:

2003 年時要跨 BBS 站轉信,除了直接 innbbsd 對接外,另外一種方式是架設 News Server,讓各站透過 News Server 轉信。前者用在轉信站比較少的情境下 (因為是 O(n^2) 的設定成本),後者則是用在轉信站比較多的時候 (是 O(n) 的設定成本)。

當時幾個大站都有自己的 News Server 可以提供這項服務,包括 Ptt 的 Wrap,KKCity 的 news.kkcity.com.tw,以及無名小站 BBS 的 News Server。但即使如此,這些站台都是人工設定,每設定一次轉信要花不少時間。

當時剛好舊的 ccreader.nctu.edu.tw 退役 (印象中是一台 Pentium III 450 與 512MB RAM 的機器,掛著 10 顆各 4.3GB 的 SCSI 硬碟),就跟 cschen 要了一個 IP 與 domain,把原來的 ccreader 重新整理後,用 PHP 寫網頁的部份,Perl 拿來處理後端對 INN 的操作。而使用條款則是自己胡亂寫一通後就上線了...

上線後除了我自己的站丟上去用以外,我就開始找人用。因為當時 Ptt 的 Wrap 常常掛掉,就跑去找 in2 講,馬上就搬過來了:


原來在 SYSOP 板的那篇找不到了,只找到這篇...

過沒多久我就跑去找簡志宇問他要不要把無名的轉信 policy 也換過來。然後隔年我去 KKCity 打工的時候也說服當時站方把 news.kkcity.com.tw 凍結。

到這邊之後,就很少看到台灣還有在自己架 News Server 了... (掩面)

之後 Group.NCTU.edu.tw 再加上 RSS 的功能 (後來爛掉了),以及加上 e-mail to usenet 功能 (這功能我自己一直在用,所以沒讓他爛掉),開發完這兩個功能後也就丟著沒開發了。最多就是想到的時候上去更新 OS & ports。

後來出社會工作,再加上 twbbs.org 商業化其實我不是很開心。整個系統放著 10 顆 SCSI 硬碟跑 RAID0,雖然有備份,但其實已經沒打算要在上面弄東西了,只是沒想到最後居然是掛在 SCSI 卡上面... 這批硬碟除了這十年外,還得加上先前 ccreader 的使用,差不多十五年還沒壞,早期的硬碟真的很神猛...

掛掉後有人問我為什麼不把備份資料弄一弄再開站,除了上面講的原因外,現在交大的環境也不適合再弄這樣的服務了... 如果要繼續服務的話我希望在外面重新寫一份,而不是拿原來的資料與架構繼續做。

最後,還是得感謝當年交大計中願意提供資源讓架設這個服務。當年我從上面學到很多東西,不僅僅是程式而已,還包括第一線客服並且了解使用者想要什麼。

Percona 的「Advanced MySQL Query Tuning」...

先前在「Percona 要講進階的 MySQL Query Tuning...」提到 Percona 所辦的 Webniar「Advanced MySQL Query Tuning」的投影片放出來了:「Advanced MySQL Query Tuning」。

這份內容需要 B+Tree 操作的背景知識才能了解。裡面講了很多 GROUP BYORDER BY 混用時的 index 技巧,以及各種奇怪的 hack 方式。

內容很有用,能吸收多少就看個人造化 :p

YouTube (Google) 允許環球唱片 (Universal Music Group,UMG) 直接移除非 UMG 所擁有版權的影片

依照環球唱片 (Universal Music Group,UMG) 提供給法院的文件中,YouTube (也就是 Google) 允許 UMG 透過 YouTube 的 CMS (Content Management System) 移除「不屬於 UMG 的影片」:「Google Deal Allegedly Lets UMG Wipe YouTube Videos It Doesn't Own」,文件 (PDF) 在:「gov.uscourts.cand.248875.14.0.pdf」這邊可以下載取得。

重點在於這份文件中第四頁的這段:

The UMG-YouTube agreement grants UMG rights to effect the removal of user-posted videos through YouTube’s Content Management System (“CMS”), based on a number of contractually specified criteria that are not limited to the infringements of copyrights owned or controlled by UMG. Klaus Decl., Ex. 4 (Klaus to Kavanaugh letter, Dec. 14, 2011). Dotcom speculates in his declaration that Universal must have sent a so-called “DMCA notification form,” such as the one he printed and attached at Ex. E to his declaration, to YouTube. Doctcom Decl. ¶ 11. But UMG (which interacts with YouTube) does not use that form when requesting the removal of material pursuant to UMG’s contract with YouTube. UMG uses YouTube’s automated CMS system.

繼續來看後續吧...