Saturday, December 24, 2016

加速 jvm 的 start up time

最近因為個人嗜好,研究了一下 clojure 語言。既然開始動手研究,自然而然,會想實驗,如果…用 clojure 來做 shell script 會如何。然後,就立刻發現了,clojure 在 shell 下啟動,哪怕是一個 hello world 程式,啟動時間就需要 2 秒以上。

time /opt/test.clj hello world real 0m2.684s user 0m2.239s sys 0m0.186s


哇,這真是太扯了,怎麼會慢到這種程度?於是我就開始研究幾個問題:
(1) JVM 是不是真的很慢?
(2) 有沒有辦法來改進這件事?

第一個問題的答案滿曲折的,因為網路上也是各家有各家的說法,而 benchmark 本身就是一個研究的題目,我也不打算做太多嚴謹的驗証,最後我的結論是:JVM 是夠快的 virtual machine ,效能並不比 native code 差太多,幾乎是可以忽略的程度, 它就只有啟動的時候比較慢而已。很多 scripting languages ,像 Ruby, Python 會考慮編譯成 JAVA bytecode ,就是為了效能考慮。

第二個答案,我試了兩個解法:
解法 1 -- jamVM ( 原理就是:把大的 openjdk 的 JVM 換成小的 jamVM )

Let’s update our clojure executable /usr/bin/clojure:
#!/bin/sh

exec java -jamvm -jar /opt/clojure.jar "$@"
Let’s try it out:
time /opt/test.clj
hello world

real  0m0.866s
user  0m0.764s
sys   0m0.076s

解法 2 -- Drip (原理:It keeps a fresh JVM spun up in reserve with the correct classpath and other JVM options so you can quickly connect and use it when needed, then throw it away. Drip hashes the JVM options and stores information about how to connect to the JVM in a directory with the hash value as its name. )





Wednesday, December 21, 2016

gitbook 與 gh-pages

最近因為要做給北京快網運維看的教材,為了讓中國也能閱讀,我用了 gitbook 。其實也就是一種比 wiki 再更簡單的 blog 而已。然而,好景不常,沒有多久,快網的人就跟我講,我發表的 gitbook 速度太慢了。他們沒有辦法閱讀。

於是我考慮,換成用 github.io 的 gh-pages 來放我的 gitbook 。本來我一直被 gitbook 的選項誤導,以為我只要讓 gitbook 的內容和我的 github 帳號同步 (sync) 就可以了,後來實驗之後,才發現,完全不是這麼回事。正確的作法是這樣子:

1. 先把 gitbook 裡的所有檔案 md 檔、圖檔,都用 git 抓到本地端的資料夾,例如 ~/book/。
2. 在本地端安裝應用程式
     npm install gitbook-cli -g
3. 將 md 檔,輸出成為靜態網站,指定 ~/book 為「圖書目錄」,指定 ~/book/docs 為「輸出目錄」
    gitbook build ~/book  ~/book/docs
4. 將 ~/book 資料夾內的內容,同步到自己 github 帳號下的 book repository 的 master branch
5. 在自己的 github 帳號做 gh-pages 的設定,讓 gh-pages 的 source 指向 master branch 裡的 docs 資料夾。


 

Thursday, December 1, 2016

bloom filter, bitmap data structure, elasticsearch

因為公司工作的關系,最近在研究 elasticsearch 。很快地,我就一頭栽進了探討 elasticsearch 與 mysql 不同的地方。就用一個常見 SQL 運算來說明好了。
SELECT AVG(age) FROM login WHERE site = 'zzz' AND host = 'kkk';
(a) where 子句的部分,在一些文章中,常稱為 Filter 操作
filter 操作在 elasticsearch 可以做相當的最佳化,因為 elasticsearch 可以使用 bitmap 來做 AND, OR 的運算。而 mysql 只能用 btree 提高查詢效率。當 where 子句的條件有多個 AND 或是 OR 的運算時,btree 比 bitmap 差許多,因為 btree 的索引無法快速地做 AND 或是 OR 的運算。
(b) AVG(age) 函數的部分,在一些文章中,常稱為 Aggregate 操作 
aggregate 操作在 elasticsearch 也會相當的好,因為 elasticsearch 有一個 doc_value 屬性,會讓它成為 column-oriented database。相比 row-oriented 資料庫, column-oriented database 存取的資料量會少非常多。因為只有 aggregate 函數作用的「欄」 (column) 會被存取,同一「列」(row) 的其它「欄」 (columns) 並不會被存取。

然後,我回想起了 bitmap data structure 也在其它地方出現過了:
(1) bloom filter
用法也是差不多,但是多了一個 hash 的運算。將元素的值透過 hash 運算,變成「索引值」 (index) 。就是元素如果存在的話,就會在對應索引值的位元標為 1 ,不存在的話,標記為 0 。
(2) 「編程珠璣」 (programming pearl) 的第一章。講如何用極少的記憶體,排序超大的檔案。由於使用 bitmap 這種資料結構,可以將 counting sort 所需要的資料結構完整地放入主記憶體,效能可以大幅提高。