標籤:des blog http os io 使用 ar for 檔案
- linear hash ETS/DETS/mnesia 都使用了linear hash演算法http://en.wikipedia.org/wiki/Linear_hashing redis dict 的實作類別似於linear hash,漸進式rehash,保證操作是O(1)。不過除了每次操作時執行一個bucket的rehash,而且每100ms內使用1ms 執行加快rehash進程。雖然雖然rehash過程漸進式的,但在key space過大時,同時使用LRU到期,buckets 這個大數組的malloc 就能讓refis卡上一陣子。曾遇到的一個案例:現網redis使用主備自動切換模式,有段時間老無故自動切換。排查發現是key space 1000kw+,切換時大量evict,bluckets 需要malloc一個*2的,也就是10M* 24 * 2 = 480M記憶體,記憶體一直處於滿地狀態,靠著LRU替換,此時需要清理出這麼大一塊,導致redis 執行個體數秒停止回應導致切換。從這個案例和記憶體利用率來看,redis 使用時盡量保證keyspace 別太大吧。 - ETS Erlang內建資料庫挑戰7000WQPS http://blog.yufeng.info/archives/876 ETS 實現很簡單,就一個記憶體字典。使用讀寫鎖,唯讀情況下達到很高的TPS,曾在我老T420筆記本 測試過字典在單核心情況下讀寫400w/s。從這個測試資料看ETS 的讀操作其實和全域記憶體字典讀取速度差不多,效率很高。寫效能因為全域鎖的關係,不可避免受限且並發越高效能越差。建議對寫入頻繁ETS做分表操作。 - DETS ETS的落地儲存方式,有單表2G大小限制,可以有cache 但預設cache 0 也就是預設讀寫都操作磁碟。前面說到DETS 是基於linear hash 儲存,hash 方式不是很磁碟友好、不是檔案塊 cache友好;cache 只是作為行級索引,沒有塊級索引。總的說DETS 和真正完整的儲存引擎還有一定差距,單獨使用價值不大,所以基本都是用於基於它的Mnesia叢集版本來使。
Since all operations performed by Dets are disk operations, it is important to realize that a single look-up operation involves a series of disk seek and read operations. For this reason, the Dets functions are much slower than the corresponding Ets functions, although Dets exports a similar interface.
Dets organizes data as a linear hash list and the hash list grows gracefully as more data is inserted into the table. Space management on the file is performed by what is called a buddy system. The current implementation keeps the entire buddy system in RAM, which implies that if the table gets heavily fragmented, quite some memory can be used up. The only way to defragment a table is to close it and then open it again with the repair option set to force.
- Mnesia 基於ETS/DETS, 的純erlang 實現的強大分散式資料庫,而disc Mnesia 表大小受dets 限制,但可以使用fragmentation,frag 類似於分區表。 使用LevelDB 替換DETS(1/4啟動時間,1/2衝突,1/3 記憶體佔用)Mnesia Backend Plugin Framework and a LevelDB-based Plugin: Roland Karlsson, Malcolm Matalkahttps://www.youtube.com/watch?v=xBcgrIOzGbQ whatsapp:disc_copies tablesPartitioned islands and fragmented tablesAll operations run async_dirtyUse key hashing to collapse all ops per keyto a single process http://stackoverflow.com/questions/23180484/why-big-companies-use-mnesia-instead-of-using-riak-or-couchdb
First of all, mnesia has no 2 gigabyte limit. It is limited on a 32bit architecture, but hardly any are present anymore for real work. And on 64bit, you are not limited to 2 gigabyte. I have seen databases on the order of several hundred gigabytes. The only problem is the initial start-up time for those.
Mnesia is built to handle:
- Very low latency K/V lookup, not necessarily linearizible.
- Proper transactions with linearizible changes (C in the CAP theorem). These are allowed to run at a much worse latency as they are expected to be relatively rare.
- On-line schema change
- Survival even if nodes fail in a cluster (where cluster is smallish, say 10-50 machines at most)
The design is such that you avoid a separate process since data is in the Erlang system already. You have QLC for datalog-like queries. And you have the ability to store any Erlang term.
Mnesia fares well if the above is what you need. Its limits are:
- You can‘t get a machine with more than 2 terabytes of memory. And loading 2 teras from scratch is going to be slow.
- Since it is a CP system and not an AP system, the loss of nodes requires manual intervention. You may not need transactions as well. You might also want to be able to seamlessly add more nodes to the system and so on. For this, Riak is a better choice.
- It uses optimistic locking which gives trouble if many processes tries to access the same row in a transaction.
Mnesia 實現分析