Home » Posts tagged "workaround"

在 Ubuntu 18.04 (Bionic) 上跑 Percona Server 5.7

Percona 的文件「Installing Percona Server on Debian and Ubuntu」這邊雖然還沒列 Ubuntu 18.04 上去,但已經有東西在裡面可以安裝了。不過還是屬於官方未正式支援的情況,用的時候自己要注意。

另外查資料的時候有看到「Ubuntu 18.04 (bionic) - percona-xtradb-cluster-server installation break」這篇提到 Percona XtraDB Cluster 裝不起來,但有 workaround 可以硬裝進去,要玩的人也可以參考一下 XD

這樣可以把 14.04 機器換一換了。(先前清點時本來以為已經是 16.04,做一些操作時才發現是 14.04...)

MySQL 的 binlog 對效能的影響

Percona 的 CTO Vadim Tkachenko 在比較 InnoDB 與 MyRocks 時意外發現了 binlog 會影響不少效能穩定性,再加上 MySQL 8.0 有改變 binlog 相關的預設值,所以他後續花了不少時間測試,寫了兩篇關於 binlog 對於 MySQL 效能的影響:「How Binary Logs (and Filesystems) Affect MySQL Performance」與「How Binary Logs Affect MySQL 8.0 Performance」。

第一篇是想要知道在 Percona Server 5.7 上開 binlog 的影響,做出來後可以看到明顯的效能波動 (因為 binlog 導致 flush 時效能暴跌):

而其中的 workaround 就是調整 flush 參數,讓他比較頻繁的小量寫入,而不是突然要寫很多資料。這樣一來對平均效能也許比較差,但對前端應用衝擊會比較小:

在測試可以看到 sync_binlog=1000 是個妥協點。各單位要自己去找出適合的數字:

The strict setting also comes with noted performance penalties. I will also test sync_binlog=1000 and sync_binlog=10000, which means perform synchronous writes of binary logs every 1000 and 10000 transactions, respectively.

另外有測試 ext4 與 XFS 是否有影響,就測試的結果看起來 ext4 比 XFS 好一些,但差距有限:

第二篇則是拿 MySQL 8.0 與 Percona Server 5.7 比較,可以發現在 MySQL 8.0 開啟 binlog 時有時會有不少的效能損失:

It seems that binary logs have quite an effect MySQL 8.0, and we see up to a 30% performance penalty as opposed to the 13% for Percona Server for MySQL 5.7.

雖是推銷一下自家產品在這塊還不錯 XD

針對 Ubuntu 16.04 + PPPoE 時,OpenNTPD 的 -s 不會在啟動時直接校正的問題 workaround...

發現機器時間跟標準時間差了 40 秒左右,結果有些服務因為會看雙方時間,就不讓我跑... XDDD

找問題找了半天,發現開機後 ntpdate 會回報找不到伺服器,看起來是網路根本就還沒通就跑起來了:

Jan 25 13:10:30 home ntpdate[757]: name server cannot be used: Temporary failure in name resolution (-3)
Jan 25 13:10:30 home ntpdate[1171]: name server cannot be used: Temporary failure in name resolution (-3)
Jan 25 13:10:30 home ntpdate[1347]: name server cannot be used: Temporary failure in name resolution (-3)
Jan 25 13:10:30 home ntpdate[1410]: name server cannot be used: Temporary failure in name resolution (-3)

而理論上 與 openntpd 加上 -s 也會做類似的事情,所以這邊就在 /etc/default/openntpd 先加上 -s,讓他開機時強制對時一次,看看能不能解... 結果也是一樣在網路還沒通的時候就跑起來而失敗了:

Jan 25 13:10:45 home ntpd[1457]: no reply received in time, skipping initial time setting

由於這台機器是 HiNet 的 PPPoE,看起來有可能是某些條件沒寫好,造成執行順序不對... 所以就找個 workaround 來解決 @_@

後來找的方法是直接到 /etc/ppp/ip-up.d/ 下放一個 script 實作 workaround,直接在 PPPoE 連上後重跑 openntpd,然後用 hwclock 寫回主機裡,下次開機的時間就會比較準一些了:

#!/bin/sh -e

/usr/sbin/service openntpd restart
/sbin/hwclock -w

不過實際上還是要找看看要怎麼把 PPPoE 掛到 networking 那層行為裡面...

讀書時間:Spectre 的攻擊方式

上次寫了 Meltdown 攻擊的讀書心得 (參考「讀書時間:Meltdown 的攻擊方式」),結果後來中獎狂流鼻水,加上 Spectre 用的手法就更複雜,慢慢看的情況就拖到最近才看完... 這邊就以讀者看過 Meltdown 那篇心得的前提來描述 Spectre。

Spectre 的精華在於 CPU 支援 branch prediction 與 out-of-order execution,也就是 CPU 遇到 branch 時會學習怎麼跑,這個資訊提供給 out-of-order execution 就可以大幅提昇執行速度。可以參考以前在「CPU Branch Prediction 的成本...」提到的效率問題。

原理的部份可以看這段程式碼:

這類型程式碼常常出現在現代程式的各種安全檢查上:確認 x 沒問題後再實際將資料拉出來處理。而我們可以透過不斷的丟 x 值進去,讓 CPU 學到以為都是 TRUE,而在 CPU 學壞之後,突然丟進超出範圍的 x,產生 branch misprediction,但卻已經因為 out-of-order execution 而讓 CPU 執行過 y = ... 這段指令,進而導致 cache 的內容改變。

然後其中讓人最驚豔的攻擊,就是論文示範了透過瀏覽器的 JavaScript 就能打的讓人不要不要的...

圖片裡,上面這段是 JavaScript 程式碼,下面則是 Chrome V8JIT 後轉成的 assembly (這是 AT&T style):

可以從這段程式碼看到,他想要透過這段 JavaScript 取出本來無法存取到的祕密值 index,然後透過 probeTable 得知 cache 的變化。

在這樣的攻擊下,你就可以取得這個 process 裡可以看到的空間,甚至極端的 case 下有可能是 kernel space (配合 Meltdown 的條件)。

不過如果你不能跑 JavaScript 也沒關係,Spectre 的論文裡也提供各種變形方式提供攻擊。像是這樣的程式碼也可以被拿來攻擊:

if (false but mispredicts as true)
    read array1[R1]
read [R2]

其中 R1 是有帶有祕密值的 register,當 array[R1] 有 cache 時,讀 [R2] 就有機會比較快,而沒有 cache 時就會比較慢 (這是因為 memory bus 被佔用的關係),在這個情境下就能夠產生 timing attack:

Suppose register R1 contains a secret value. If the speculatively executed memory read of array1[R1] is a cache hit, then nothing will go on the memory bus and the read from [R2] will initiate quickly. If the read of array1[R1] is a cache miss, then the second read may take longer, resulting in different timing for the victim thread.

所以相同道理,利用乘法器被佔用的 timing attack 也可以產生攻擊:

if (false but mispredicts as true)
    multiply R1, R2
multiply R3, R4

在論文裡面提到相當多的方法 (甚至連 branch target buffers (BTB) 都可以拿來用),就麻煩去論文裡看了。現在用 cache 算是很有效的方式,所以攻擊手法主要都是透過 cache 在取得資訊。

Spectre 論文提到的 mitigation (workaround) 是透過 mfencelfence 強制程式碼的順序,但這表示 compiler 要針對所有的 branch 加上這段,對效能影響應該蠻明顯的:

In addition, of the three user-mode serializing instructions listed by Intel, only cpuid can be used in normal code, and it destroys many registers. The mfence and lfence (but not sfence) instructions also appear to work, with the added benefit that they do not destroy register contents. Their behavior with respect to speculative execution is not defined, however, so they may not work in all CPUs or system configurations.

Google 推出的 Retpoline 則是想要避免這個問題。Google 在「Retpoline: a software construct for preventing branch-target-injection」這邊詳細說明了 Retpoline 的原理與方法,採取的方向是控制 speculative execution:

However, we may manipulate its generation to control speculative execution while modifying the visible, on-stack value to direct how the branch is actually retired.

這個方式是抽換掉 jmpcall 兩個指令,以 *%r11 為例,他將 jmp *%r11call *%r11 改成 jmp retpoline_r11_trampolinecall retpoline_r11_trampoline (這邊的 jmp 指的是所有 jump 系列的指令,像是 jz 之類的):

retpoline_r11_trampoline:
  call set_up_target;
capture_spec:        
  pause;
  jmp capture_spec;
set_up_target:
  mov %r11, (%rsp); 
  ret;

藉由抽換 %rsp 內容跳回正確位置,然後也利用這樣的程式結構控制 CPU 的 speculative execution。

而在效能損失上,已經有測試報告出來了。其實並沒有像 Google 說的那麼無痛,還是會因為應用差異而有不同等級的效能損失... 可以看到有些應用其實還是很痛:「Benchmarking Linux With The Retpoline Patches For Spectre」。

下半年新出的 CPU 應該會考慮這些問題了吧,不過不知道怎麼提供解法 @_@

Ubuntu 開始更新 Kernel 了...

這波 CPU 安全問題,UbuntuLinux Kernel 的更新計畫 (workaround patch) 放在「Information Leak via speculative execution side channel attacks (CVE-2017-5715, CVE-2017-5753, CVE-2017-5754 aka Spectre and Meltdown)」這邊。

不是所有版本的 kernel 都有更新,像是我之前跑 4.10 發現這次沒在清單內,就換成 linux-image-generic-hwe-16.04-edge 了... 換完後需要再裝 linux-headers-generic-hwe-16.04-edge,然後把舊的 kernel 都清乾淨,最後 nvidia-387 需要重新編過。

這次苦哈哈啊...

Etsy 介紹的 Cache Smearing

Etsy 的 engineering blog 上提到了他們怎麼設計 cache 機制:「How Etsy caches: hashing, Ketama, and cache smearing」。

使用 consistent hash 已經是基本款了,文章裡花了一些篇幅介紹為什麼要用 consistent hash。

後半段則是有了 consistent hash 後會遇到的問題,也就是講 hot key 怎麼處理:有些資料非常熱 (常常被存取),就算用 consistent hash 也還是有可能搞爆單一機器。

他們做了幾件事情,第一件事情是設計 cache smearing 機制,把單一資料加上 random key,使得不同的 key 會打散到不同的機器上:

Let’s take an example of a hot key popular_user_data. This key is read often (since the user is popular) and is hashed to pool member 3. Cache smearing appends a random number in a small range (say, [0, 8)) to the key before each read or write. For instance, successive reads might look up popular_user_data3, popular_user_data1, and popular_user_data6. Because the keys are different, they will be hashed to different hosts. One or more may still be on pool member 3, but not all of them will be, sharing the load among the pool.

第二件事情則是監控哪些 key 比較熱門:

We’ve seen this problem many times over the years, using mctop, memkeys, and our distributed tracing tools to track down hot keys.

第三件事情是維護 hot key 的清單 (不是每個 key 都會上 cache smearing):

We manually add cache smearing to only our hottest keys, leaving keys that are less read-heavy efficiently stored on a single host.

是個當規模大到單一 hot key 會讓單台伺服器撐不住時的 workaround...

HTTP/2 時代的 API 設計

在「Let’s Stop Building APIs Around a Network Hack」這邊提到了以前為了解決 HTTP/1.1 的問題而發展出來的 workaround,在 2015 年發展出來的 HTTP/2 從底層直接解了不少問題,加上很快被許多瀏覽器支援 (就算不支援 HTTP/2 也只是降到 HTTP/1.1 跑,比較慢而已):

Guess what else was released in May 2015? RFC 7540, otherwise known as HTTP/2. In retrospect this seems highly poetic, as HTTP/2 kinda makes the compound document aspect of JSON-API a little bit pointless, and compound documents to me go hand in hand with what JSON-API is as a standard.

2012 年在 MOPCON 第一屆講的「API Design Optimized for Mobile Platform」剛好就是這個主題:

有種懷念感... XD

在 Mac 上快速換輸入法的方法:Kawa

三月的時候在「在 Mac 上快速切換輸入法」這邊提到了 IMEShortcuts,但有時候還是不會生效...

在「GitHub 中那些不错的免费软件」這篇裡面提到了 open source 的 utatti/kawa 這個專案,裡面有針對 CJKV 輸入法的 bug 提供 workaround,就給個機會測試看看:

There is a known bug in the TIS library of macOS that switching keyboard layouts doesn't work well when done programmatically, especially between complex input sources like CJKV.

而且最近變得可以用 Homebrew 管理了,這樣之後升級比較方便。

Amazon EC2 要推出 x1e.32xlarge,4TB RAM 的機器

剛剛 Amazon EC2 公佈的消息,要再推出記憶體大怪物機器 x1e.32xlarge:「EC2 In-Memory Processing Update: Instances with 4 to 16 TB of Memory + Scale-Out SAP HANA to 34 TB」。

Later this year we plan to make the x1e.32xlarge instances available in several AWS regions, in both On-Demand and Reserved Instance form. These instances will offer 4 TB of DDR4 memory (twice as much as the x1.32xlarge), 128 vCPUs (four 2.3 GHz Intel® Xeon® E7 8880 v3 processors), high memory bandwidth, and large L3 caches.

雖然都是拿 SAP 來舉例,但這也是當系統碰到瓶頸時搶時間的方法 (也就是當 happy problem 發生時的 workaround)。

不知道這種機器實際買起來多少錢 XDDD

IPFS 分散式 Web 服務,以及 ipfspics 圖片儲存

IPFS (InterPlanetary File System),或是被稱作 The Permanent Web。

起因在於目前 HTTP (Web) 在設計時是 1990 年代的想法,許多威脅在當時並不明顯。而到了現在,來自攻擊者的威脅與政府監控的威脅使得必須在 HTTP (Web) 上架構許多 workaround。

最知名的 workaround 就是 HTTPS 以及對應的 CA 架構了,前者因為 HTTPS 協定本身高度複雜,實作的單位經常出錯而產生安全漏洞。而後者靠著大量的稽核檢查來避免出問題,不過畢竟還是 workaround,常常會有一堆「誤發」的狀況發生。

另外 HTTP 發展到現在其實是去中心化「Decenteralized」的架構,政府單位可以抓著其中幾個結點就可以大量監控,而 IPFS 想要做到真正的分散式「Distributed」:

前陣子 IPFS 在 GitHub 上放出了 prototype 讓大家玩:「ipfs implementation in go.」,而最近有人把這個點子實作成 image hosting:「ipfs.pics」(一樣是放在 GitHub 上),並且提供對應的網頁上傳介面:「Decentralized picture hosting in ipfs」。

我試著丟一張圖片上 ipfs.pics 後,得到的 hash 值是 QmRpNqK33gDDKdu8y6Wx5DQsuiJbsnwojNzH5nUwCpwoS9,也可以在 IPFS 看到這張圖:

來玩看看好了 :o

Archives