Graph on Riak
當初因為 Neo4j 的 scale out 不理想, 又沒有更好的可以替代, 所以從 graph 轉到 Riak. 但凡事都有辛苦的地方, 沒有什麼東西全部都有. 要效能就用 Redis 而非一般 NoSQL ? 要 Graph 就用 Neo4j 而非 Key-Value. 而想要在 Key-Value 上實現 Graph, 則不是太簡單的一件事. 以我們現在的做法, 簡單講就是先抓到 member 的 friends, 再 async 抓他們的 friends, 看幾層抓幾次.. 聽起來很暴力, 但效能還蠻快的.. 而為了時時都有抓到最新的 relationships, 定期的做 graph traverse.. 在每次 traverse 完後, 也會將關係寫入資料庫, 比如, 會更新 member 的 depth2 friends. 這樣下次就不需要跑 graph traverse, 可以直接抓取 depth2 friends. 效能可以接受的原因在於, Riak 有個功能是可以把 bucket 中的 key 全部 list 出來. 所以只需要存 relationship 在某個 bucket 中. 以 fof 來說, 將下列 keys 存在 member1-friends : member3, member5, member7
即可透過 /riak/member1-friends?keys=true&props=false 來取得 rels. 而且, 因為只讀 keys, 不讀 value, 速度非常快. 當 key 太多時, 也可以透過 stream 的方式來批次處理.
我們試過 secondary-index 來處理 rels. 但是每個 node 有太多關係, 而 secondary-index 只是存在 object 裡 meta. 每次要更新時需要將整個 meta 抓回, 更新, 再存回去.. 操作上感覺不是太理想..
我們也嘗試過 map-reduce. 但 riak 的 js-map-reduce 其實 performance 並不理想. 儘管我們調整過 configuration, 比如將 map_js_vm_count 拉高, 將. etc. JS vm 速度不好是可以理解, 而 riak 官方也說過, JS VM 比較像是讓你好上手. 等到確定了再改寫成 erlang ? 但改用 erlang 寫之後, 速度仍舊不滿意. 推估是因為 riak map 時, 仍舊會把 value 抓回.
為了增進效能, 我們也將同樣的東西放在 redis 上處理過. redis 顯然是快上許多.. 但因為 memory 有限, 所以也只能將部分資料 port 到 redis 處理..














