高テス協会会長が, テストステロンに関する情報をお届けします.

(dm-lc report) dm-lcのupstream化を目指します

dm-lcがカテゴリされるSSDを利用したキャッシング技術は, Linuxコミュニティで現在, とても熱い分野です. 最近では, bcache(Google)がまずアップストリームにマージされ, それからdm-cache(Redhat)がマージされました. 他にも, FlashCache(Facebook)の改善であるenhanceIO(sTec)がML上で議論の対象となっています. そのsTecは, 340MドルでWestern Digitalに買収されることが決まっています. このことから, Linuxコミュニティのみならず, ビジネスの世界でも注目されているといえます. device-mapper自体, 3.11ではdm-switchがマージされるなど, Linuxコミュニティでも注目されています.

dm-lcは, これら先行するキャッシュ技術とは趣の異なるキャッシュ技術です*1. 私の考えでは, dm-lcはアップストリームにマージされる価値があります. アップストリームにマージされることにより, 広くの人に使われます. また, 議論されます. 今まで粛々と実装や検証を進めてきましたが, 今が時と思います. dm-lcはアップストリームへの採用を狙うことにします. アップストリーム活動により, 私自身がワンランク上の開発者に成長出来ることは, 私にとってだけでなく, たぶん世界にとっても利益です. 私にはそれだけのポテンシャルがあると信じています. dm-lcは, 私の成長においては踏み台に過ぎません.

dm-lcは大まかに, カーネルコード(Driver/dm-lc.c)と, 管理ツール(Admin/)で構成されます. Githubのリポジトリでは前者について, 3.2からアップストリームに採用される以前のカーネルまでのportable codeを保守します. アップストリーム採用後は, 二重開発になりますが, アップストリームコードのメンテナンスと, portable codeの主にhotfixを中心に進めていきます. 後者については, アップストリームもportableも共通に使うことにします. 管理ツールがカーネルから分離されている例はファイルシステムで少なからず存在しますから, この思想に歪みはありません. 私の考えでは, 管理ツールに対してカーネル側からインターフェイスを保守し続けるのは容易です.

アップストリーム化まではまず, portable codeのレベルでコードを満足の行く形にして, そこからfeature/upstreamというブランチを作成し, そこで開発を進めます. linux-nextに追従すれば良いのでしたっけ?Linux開発プロセスは複雑過ぎます.


  • checkpatchによって, 残るwarningは17個のLINUX_VERSION_CODE警告です. もともと800個以上あったので, 非常に大変でした. 80col ruleには今も苦しめられています. Twitterでの議論により, コード改善も行われました.
  • DMDEBUGを"一匹残らず駆逐"しました. アップストリームカーネルでは, DMDEBUGはdm-flakeyで一つ使われている限りです. 排除すべきです.
  • Documentation/device-mapper/dm-lc.txtに格納するドキュメントを執筆しました. 英文の改善に貢献してくれる人がいたら嬉しいです.
  • Kconfigをさらっと書きました. 本格的な感じがしてかっこいいですね.


dm-lcでは, コードレビューをしてくれる人を募集します. 人材は, C言語が読めることがmustであり, カーネルAPIへの知識があることが望ましい. MLに投げる前にもう一段良いコードにしたいです. Twitter or E-mailでご連絡ください.
upstream活動に関する基本的な疑問は, Twitterで発信します. これに対して協力的にされると嬉しいです.

dm-lc.txtのドラフトは以下です. 英文に改善が必要であれば, Twitter or E-mailで連絡か, Pull Requestでお願いします.


dm-lc provides write-back log-structured caching.
It batches random writes into a big sequential write.

1. Setup
dm-lc is composed of two target_type instances named lc and lc-mgr.
lc is responsible for creating virtual volumes and controlling ios and 
lc-mgr is reponsible for managing
formatting/initializing/destructing cache devices on the other hand.
Operating dm-lc through these native interfaces are not recommended.

To easily get started with dm-lc, nice userland tools are provided in
where you are also accesible to portable dm-lc kernel code
that supports since 3.2 kernel until before dm-lc staged upstream, 3.x.
please git clone it.

To install the tools, move under Admin directory and run
    python install
and now you are dm-lc admin.

2. Example scripts
Let's create a virtual volume named myLV
backed by /dev/myVg/myBacking
and use /dev/myCache as a cache device.

myLV -- (backing store) /dev/myVg/myBacking
     -- (cache device)  /dev/myCache

Step 1
Format myCache and
resume myCache

Resuming builds in-memory structures like hashtables
reading from the metadata on myCache.

    lc-format-cache /dev/myCache
    lc-resume 3 /dev/myCache

Step 2
Create myLV and
attach to myCache

    lc-create myLV 5 /dev/myVg/myBacking
    lc-attach 5 3

Step 3
Start userland daemon

dm-lc provides daemon program
that autonomously control the module behavior
such as write-back from myCache to myBacking
which dm-lc calls "migration".

    lc-daemon start

Step 4
Terminate myLV

Safely terminating myLV already attached to myCache
is easy to mistake and that's why dm-lc provides these admin tools.
myLV can not detach from myCache
until all the dirty caches on myCache
are migrated to myBacking 

    lc-detach 5
    lc-daemon stop
    lc-free-cache 3
    lc-remove 5

3. Sysfs
dm-lc provides some sysfs interfaces to control the module behavior.
The sysfs tree is located under /sys/module/dm_lc.

|-- devices
|   `-- 5
|       |-- cache_id
|       |-- dev
|       |-- device -> ../../../../devices/virtual/block/dm-0
|       |-- migrate_threshold
|       |-- nr_dirty_caches
|-- caches
|   `-- 3
|       |-- allow_migrate
|       |-- barrier_deadline_ms
|       |-- commit_super_block
|       |-- commit_super_block_interval
|       |-- device -> ../../../../devices/virtual/block/dm-1
|       |-- flush_current_buffer
|       |-- flush_current_buffer_interval
|       |-- force_migrate
|       |-- last_flushed_segment_id
|       |-- last_migrated_segment_id
|       `-- update_interval

4. Technical Issues
There are not a few technical issues 
that distinguishes dm-lc from other similar cache softwares.

4.1 RAM buffer and immediate completion
dm-lc allocated RAM buffers of 64MB in total by default.
All of the writes are first stored in one of these RAM buffers
and immediate completion is notified to the upper layer
that is usually in few microseconds that is unimaginably fast.

4.2 Metadata durability
After RAM buffer gets full or some deadline comes
dm-lc creates segment log that gathers RAM buffer and its metadata.
Metadata have information such as connection between
address in cache device and the counterpart in backing store.
As the segment log finally is written to persistent cache device,
any data will not be lost after machine failure.

4.3 Asynchronous log flushing
dm-lc has a background worker called flush daemon.
Flushing segment log starts from simplly queueing the flush task.
Flush daemon in background asynchronously checks if the queue has some tasks
and actually executes the tasks if exists.
The fact that the upper layer doesn't block in queueing the task
maximizes the write throughput
that is 259MB/s random writes with cache device of 266MB/s sequential write
which is only 4% loss
and 1.5GB/s theoritically with a fast enough cache like PCI-e SSDs.

4.4 Asynchronous and automated migration
Some time after a log segment is flushed to cache device
it will be migrated to backing store.
Migrate daemon is also a background worker 
that periodically check if log segments to migrate exist.

Restlessly migrating highly loads backing store
so migration is better to execute when the backing store is in low load.
lc-daemon in userland surveils the load of backing store
and turns migration on and off according to the load.

4.5 Lazy handling of REQ_FUA and REQ_FLUSH bios
Some applications such as XFS and databases often submit SYNC write that
leads to bios flagged with REQ_FUA or REQ_FLUSH.
Handling these irregular bios immediately and thus synchronously
desparately deteriorates the whole throughput.
To address this issue, dm-lc handles these bios lazily or in deferred manner.
Completion related to these bios will not be done until 
they are written persistently to the cache device
so this storategy doesn't break the semantics.
In worst case, a bio with some of these flags
is completed in deadline period that is described
in barrier_deadline_ms in sysfs.

*1:あるユースケースにおいては, dm-lcは他の技術と比較するまでもなく正解です. しかし別のユースケースでは, 比較するまでもなく不正解です. 他のキャッシュソフトウェアは, どのユースケースにおいても比較しなければなりません. これは, 基本思想の違いが産む性質です