← Documents Documentation/admin-guide/bcache.rst GitHub 원문 ↗

Linux 6.18.37 · Administration / Storage

A block layer cache (bcache)

SSD를 block-layer cache로 사용하는 bcache의 설계, format·attach·복구·교체, 성능 tuning과 backing/cache-set/cache-device sysfs를 설명합니다.

Source pathDocumentation/admin-guide/bcache.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

Design and setup

bcache.rst:1-97

SSD bucket·btree/log 설계, cache mode, sequential bypass와 초기 format/register 절차를 설명합니다.

Attaching

bcache.rst:98-126

Cache-set UUID attach와 cache 영구 손실 시 backing-device 강제 실행 위험을 다룹니다.

Error handling

bcache.rst:127-150

Read, writethrough, writeback과 detach의 cache I/O error 처리를 구분합니다.

Recovery cookbook

bcache.rst:151-209

Missing cache, registration bug와 backing filesystem offset 복구 절차를 제공합니다.

Management cookbook

bcache.rst:210-316

Cache wipe·재생성·교체, dm-crypt layering과 reference 해제를 설명합니다.

Performance troubleshooting

bcache.rst:317-402

RAID alignment, writeback, sequential cutoff, congestion throttle과 cache warmup을 조정합니다.

Backing-device sysfs

bcache.rst:403-487

Backing association, mode, state, sequential detection과 writeback control attribute를 정리합니다.

Backing statistics

bcache.rst:488-510

Cache bypass, hit/miss와 miss-collision 통계를 설명합니다.

Cache-set sysfs

bcache.rst:511-573

Btree geometry, device links, error decay, journal과 set lifecycle을 설명합니다.

Internal statistics

bcache.rst:574-603

Journal·btree·race·garbage-collection 내부 통계를 제공합니다.

Cache-device sysfs

bcache.rst:604-653

Cache geometry, replacement policy, discard, freelist와 write accounting을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ============================
2 A block layer cache (bcache)
3 ============================
4
5 Say you've got a big slow raid 6, and an ssd or three. Wouldn't it be
6 nice if you could use them as cache... Hence bcache.
7
8 The bcache wiki can be found at:
9 https://bcache.evilpiepirate.org
10
11 This is the git repository of bcache-tools:
12 https://git.kernel.org/pub/scm/linux/kernel/git/colyli/bcache-tools.git/
13
14 The latest bcache kernel code can be found from mainline Linux kernel:
15 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
16
17 It's designed around the performance characteristics of SSDs - it only allocates
18 in erase block sized buckets, and it uses a hybrid btree/log to track cached
19 extents (which can be anywhere from a single sector to the bucket size). It's
20 designed to avoid random writes at all costs; it fills up an erase block
21 sequentially, then issues a discard before reusing it.
22
23 Both writethrough and writeback caching are supported. Writeback defaults to
24 off, but can be switched on and off arbitrarily at runtime. Bcache goes to
25 great lengths to protect your data - it reliably handles unclean shutdown. (It
26 doesn't even have a notion of a clean shutdown; bcache simply doesn't return
27 writes as completed until they're on stable storage).
28
29 Writeback caching can use most of the cache for buffering writes - writing
30 dirty data to the backing device is always done sequentially, scanning from the
31 start to the end of the index.
32
33 Since random IO is what SSDs excel at, there generally won't be much benefit
34 to caching large sequential IO. Bcache detects sequential IO and skips it;
35 it also keeps a rolling average of the IO sizes per task, and as long as the
36 average is above the cutoff it will skip all IO from that task - instead of
37 caching the first 512k after every seek. Backups and large file copies should
38 thus entirely bypass the cache.
39
40 In the event of a data IO error on the flash it will try to recover by reading
41 from disk or invalidating cache entries. For unrecoverable errors (meta data
42 or dirty data), caching is automatically disabled; if dirty data was present
43 in the cache it first disables writeback caching and waits for all dirty data
44 to be flushed.
45
46 Getting started:
47 You'll need bcache util from the bcache-tools repository. Both the cache device
48 and backing device must be formatted before use::
49
50 bcache make -B /dev/sdb
51 bcache make -C /dev/sdc
52
53 `bcache make` has the ability to format multiple devices at the same time - if
54 you format your backing devices and cache device at the same time, you won't
55 have to manually attach::
56
57 bcache make -B /dev/sda /dev/sdb -C /dev/sdc
58
59 If your bcache-tools is not updated to latest version and does not have the
60 unified `bcache` utility, you may use the legacy `make-bcache` utility to format
61 bcache device with same -B and -C parameters.
62
63 bcache-tools now ships udev rules, and bcache devices are known to the kernel
64 immediately. Without udev, you can manually register devices like this::
65
66 echo /dev/sdb > /sys/fs/bcache/register
67 echo /dev/sdc > /sys/fs/bcache/register
68
69 Registering the backing device makes the bcache device show up in /dev; you can
70 now format it and use it as normal. But the first time using a new bcache
71 device, it'll be running in passthrough mode until you attach it to a cache.
72 If you are thinking about using bcache later, it is recommended to setup all your
73 slow devices as bcache backing devices without a cache, and you can choose to add
74 a caching device later.
75 See 'ATTACHING' section below.
76
77 The devices show up as::
78
79 /dev/bcache<N>
80
81 As well as (with udev)::
82
83 /dev/bcache/by-uuid/<uuid>
84 /dev/bcache/by-label/<label>
85
86 To get started::
87
88 mkfs.ext4 /dev/bcache0
89 mount /dev/bcache0 /mnt
90
91 You can control bcache devices through sysfs at /sys/block/bcache<N>/bcache .
92 You can also control them through /sys/fs//bcache/<cset-uuid>/ .
93
94 Cache devices are managed as sets; multiple caches per set isn't supported yet
95 but will allow for mirroring of metadata and dirty data in the future. Your new
96 cache set shows up as /sys/fs/bcache/<UUID>
97
98 Attaching
99 ---------
100
101 After your cache device and backing device are registered, the backing device
102 must be attached to your cache set to enable caching. Attaching a backing
103 device to a cache set is done thusly, with the UUID of the cache set in
104 /sys/fs/bcache::
105
106 echo <CSET-UUID> > /sys/block/bcache0/bcache/attach
107
108 This only has to be done once. The next time you reboot, just reregister all
109 your bcache devices. If a backing device has data in a cache somewhere, the
110 /dev/bcache<N> device won't be created until the cache shows up - particularly
111 important if you have writeback caching turned on.
112
113 If you're booting up and your cache device is gone and never coming back, you
114 can force run the backing device::
115
116 echo 1 > /sys/block/sdb/bcache/running
117
118 (You need to use /sys/block/sdb (or whatever your backing device is called), not
119 /sys/block/bcache0, because bcache0 doesn't exist yet. If you're using a
120 partition, the bcache directory would be at /sys/block/sdb/sdb2/bcache)
121
122 The backing device will still use that cache set if it shows up in the future,
123 but all the cached data will be invalidated. If there was dirty data in the
124 cache, don't expect the filesystem to be recoverable - you will have massive
125 filesystem corruption, though ext4's fsck does work miracles.
126
127 Error Handling
128 --------------
129
130 Bcache tries to transparently handle IO errors to/from the cache device without
131 affecting normal operation; if it sees too many errors (the threshold is
132 configurable, and defaults to 0) it shuts down the cache device and switches all
133 the backing devices to passthrough mode.
134
135 - For reads from the cache, if they error we just retry the read from the
136 backing device.
137
138 - For writethrough writes, if the write to the cache errors we just switch to
139 invalidating the data at that lba in the cache (i.e. the same thing we do for
140 a write that bypasses the cache)
141
142 - For writeback writes, we currently pass that error back up to the
143 filesystem/userspace. This could be improved - we could retry it as a write
144 that skips the cache so we don't have to error the write.
145
146 - When we detach, we first try to flush any dirty data (if we were running in
147 writeback mode). It currently doesn't do anything intelligent if it fails to
148 read some of the dirty data, though.
149
150
151 Howto/cookbook
152 --------------
153
154 A) Starting a bcache with a missing caching device
155
156 If registering the backing device doesn't help, it's already there, you just need
157 to force it to run without the cache::
158
159 host:~# echo /dev/sdb1 > /sys/fs/bcache/register
160 [ 119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered
161
162 Next, you try to register your caching device if it's present. However
163 if it's absent, or registration fails for some reason, you can still
164 start your bcache without its cache, like so::
165
166 host:/sys/block/sdb/sdb1/bcache# echo 1 > running
167
168 Note that this may cause data loss if you were running in writeback mode.
169
170
171 B) Bcache does not find its cache::
172
173 host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach
174 [ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set
175 [ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8
176 [ 1933.478179] : cache set not found
177
178 In this case, the caching device was simply not registered at boot
179 or disappeared and came back, and needs to be (re-)registered::
180
181 host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register
182
183
184 C) Corrupt bcache crashes the kernel at device registration time:
185
186 This should never happen. If it does happen, then you have found a bug!
187 Please report it to the bcache development list: linux-bcache@vger.kernel.org
188
189 Be sure to provide as much information that you can including kernel dmesg
190 output if available so that we may assist.
191
192
193 D) Recovering data without bcache:
194
195 If bcache is not available in the kernel, a filesystem on the backing
196 device is still available at an 8KiB offset. So either via a loopdev
197 of the backing device created with --offset 8K, or any value defined by
198 --data-offset when you originally formatted bcache with `bcache make`.
199
200 For example::
201
202 losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev
203
204 This should present your unmodified backing device data in /dev/loop0
205
206 If your cache is in writethrough mode, then you can safely discard the
207 cache device without losing data.
208
209
210 E) Wiping a cache device
211
212 ::
213
214 host:~# wipefs -a /dev/sdh2
215 16 bytes were erased at offset 0x1018 (bcache)
216 they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
217
218 After you boot back with bcache enabled, you recreate the cache and attach it::
219
220 host:~# bcache make -C /dev/sdh2
221 UUID: 7be7e175-8f4c-4f99-94b2-9c904d227045
222 Set UUID: 5bc072a8-ab17-446d-9744-e247949913c1
223 version: 0
224 nbuckets: 106874
225 block_size: 1
226 bucket_size: 1024
227 nr_in_set: 1
228 nr_this_dev: 0
229 first_bucket: 1
230 [ 650.511912] bcache: run_cache_set() invalidating existing data
231 [ 650.549228] bcache: register_cache() registered cache device sdh2
232
233 start backing device with missing cache::
234
235 host:/sys/block/md5/bcache# echo 1 > running
236
237 attach new cache::
238
239 host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach
240 [ 865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1
241
242
243 F) Remove or replace a caching device::
244
245 host:/sys/block/sda/sda7/bcache# echo 1 > detach
246 [ 695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7
247
248 host:~# wipefs -a /dev/nvme0n1p4
249 wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy
250 Ooops, it's disabled, but not unregistered, so it's still protected
251
252 We need to go and unregister it::
253
254 host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0
255 lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/
256 host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop
257 kernel: [ 917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered
258
259 Now we can wipe it::
260
261 host:~# wipefs -a /dev/nvme0n1p4
262 /dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81
263
264
265 G) dm-crypt and bcache
266
267 First setup bcache unencrypted and then install dmcrypt on top of
268 /dev/bcache<N> This will work faster than if you dmcrypt both the backing
269 and caching devices and then install bcache on top. [benchmarks?]
270
271
272 H) Stop/free a registered bcache to wipe and/or recreate it
273
274 Suppose that you need to free up all bcache references so that you can
275 fdisk run and re-register a changed partition table, which won't work
276 if there are any active backing or caching devices left on it:
277
278 1) Is it present in /dev/bcache* ? (there are times where it won't be)
279
280 If so, it's easy::
281
282 host:/sys/block/bcache0/bcache# echo 1 > stop
283
284 2) But if your backing device is gone, this won't work::
285
286 host:/sys/block/bcache0# cd bcache
287 bash: cd: bcache: No such file or directory
288
289 In this case, you may have to unregister the dmcrypt block device that
290 references this bcache to free it up::
291
292 host:~# dmsetup remove oldds1
293 bcache: bcache_device_free() bcache0 stopped
294 bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered
295
296 This causes the backing bcache to be removed from /sys/fs/bcache and
297 then it can be reused. This would be true of any block device stacking
298 where bcache is a lower device.
299
300 3) In other cases, you can also look in /sys/fs/bcache/::
301
302 host:/sys/fs/bcache# ls -l */{cache?,bdev?}
303 lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/
304 lrwxrwxrwx 1 root root 0 Mar 5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/
305 lrwxrwxrwx 1 root root 0 Mar 5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/
306
307 The device names will show which UUID is relevant, cd in that directory
308 and stop the cache::
309
310 host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop
311
312 This will free up bcache references and let you reuse the partition for
313 other purposes.
314
315
316
317 Troubleshooting performance
318 ---------------------------
319
320 Bcache has a bunch of config options and tunables. The defaults are intended to
321 be reasonable for typical desktop and server workloads, but they're not what you
322 want for getting the best possible numbers when benchmarking.
323
324 - Backing device alignment
325
326 The default metadata size in bcache is 8k. If your backing device is
327 RAID based, then be sure to align this by a multiple of your stride
328 width using `bcache make --data-offset`. If you intend to expand your
329 disk array in the future, then multiply a series of primes by your
330 raid stripe size to get the disk multiples that you would like.
331
332 For example: If you have a 64k stripe size, then the following offset
333 would provide alignment for many common RAID5 data spindle counts::
334
335 64k * 2*2*2*3*3*5*7 bytes = 161280k
336
337 That space is wasted, but for only 157.5MB you can grow your RAID 5
338 volume to the following data-spindle counts without re-aligning::
339
340 3,4,5,6,7,8,9,10,12,14,15,18,20,21 ...
341
342 - Bad write performance
343
344 If write performance is not what you expected, you probably wanted to be
345 running in writeback mode, which isn't the default (not due to a lack of
346 maturity, but simply because in writeback mode you'll lose data if something
347 happens to your SSD)::
348
349 # echo writeback > /sys/block/bcache0/bcache/cache_mode
350
351 - Bad performance, or traffic not going to the SSD that you'd expect
352
353 By default, bcache doesn't cache everything. It tries to skip sequential IO -
354 because you really want to be caching the random IO, and if you copy a 10
355 gigabyte file you probably don't want that pushing 10 gigabytes of randomly
356 accessed data out of your cache.
357
358 But if you want to benchmark reads from cache, and you start out with fio
359 writing an 8 gigabyte test file - so you want to disable that::
360
361 # echo 0 > /sys/block/bcache0/bcache/sequential_cutoff
362
363 To set it back to the default (4 mb), do::
364
365 # echo 4M > /sys/block/bcache0/bcache/sequential_cutoff
366
367 - Traffic's still going to the spindle/still getting cache misses
368
369 In the real world, SSDs don't always keep up with disks - particularly with
370 slower SSDs, many disks being cached by one SSD, or mostly sequential IO. So
371 you want to avoid being bottlenecked by the SSD and having it slow everything
372 down.
373
374 To avoid that bcache tracks latency to the cache device, and gradually
375 throttles traffic if the latency exceeds a threshold (it does this by
376 cranking down the sequential bypass).
377
378 You can disable this if you need to by setting the thresholds to 0::
379
380 # echo 0 > /sys/fs/bcache/<cache set>/congested_read_threshold_us
381 # echo 0 > /sys/fs/bcache/<cache set>/congested_write_threshold_us
382
383 The default is 2000 us (2 milliseconds) for reads, and 20000 for writes.
384
385 - Still getting cache misses, of the same data
386
387 One last issue that sometimes trips people up is actually an old bug, due to
388 the way cache coherency is handled for cache misses. If a btree node is full,
389 a cache miss won't be able to insert a key for the new data and the data
390 won't be written to the cache.
391
392 In practice this isn't an issue because as soon as a write comes along it'll
393 cause the btree node to be split, and you need almost no write traffic for
394 this to not show up enough to be noticeable (especially since bcache's btree
395 nodes are huge and index large regions of the device). But when you're
396 benchmarking, if you're trying to warm the cache by reading a bunch of data
397 and there's no other traffic - that can be a problem.
398
399 Solution: warm the cache by doing writes, or use the testing branch (there's
400 a fix for the issue there).
401
402
403 Sysfs - backing device
404 ----------------------
405
406 Available at /sys/block/<bdev>/bcache, /sys/block/bcache*/bcache and
407 (if attached) /sys/fs/bcache/<cset-uuid>/bdev*
408
409 attach
410 Echo the UUID of a cache set to this file to enable caching.
411
412 cache_mode
413 Can be one of either writethrough, writeback, writearound or none.
414
415 clear_stats
416 Writing to this file resets the running total stats (not the day/hour/5 minute
417 decaying versions).
418
419 detach
420 Write to this file to detach from a cache set. If there is dirty data in the
421 cache, it will be flushed first.
422
423 dirty_data
424 Amount of dirty data for this backing device in the cache. Continuously
425 updated unlike the cache set's version, but may be slightly off.
426
427 label
428 Name of underlying device.
429
430 readahead
431 Size of readahead that should be performed. Defaults to 0. If set to e.g.
432 1M, it will round cache miss reads up to that size, but without overlapping
433 existing cache entries.
434
435 running
436 1 if bcache is running (i.e. whether the /dev/bcache device exists, whether
437 it's in passthrough mode or caching).
438
439 sequential_cutoff
440 A sequential IO will bypass the cache once it passes this threshold; the
441 most recent 128 IOs are tracked so sequential IO can be detected even when
442 it isn't all done at once.
443
444 sequential_merge
445 If non zero, bcache keeps a list of the last 128 requests submitted to compare
446 against all new requests to determine which new requests are sequential
447 continuations of previous requests for the purpose of determining sequential
448 cutoff. This is necessary if the sequential cutoff value is greater than the
449 maximum acceptable sequential size for any single request.
450
451 state
452 The backing device can be in one of four different states:
453
454 no cache: Has never been attached to a cache set.
455
456 clean: Part of a cache set, and there is no cached dirty data.
457
458 dirty: Part of a cache set, and there is cached dirty data.
459
460 inconsistent: The backing device was forcibly run by the user when there was
461 dirty data cached but the cache set was unavailable; whatever data was on the
462 backing device has likely been corrupted.
463
464 stop
465 Write to this file to shut down the bcache device and close the backing
466 device.
467
468 writeback_delay
469 When dirty data is written to the cache and it previously did not contain
470 any, waits some number of seconds before initiating writeback. Defaults to
471 30.
472
473 writeback_percent
474 If nonzero, bcache tries to keep around this percentage of the cache dirty by
475 throttling background writeback and using a PD controller to smoothly adjust
476 the rate.
477
478 writeback_rate
479 Rate in sectors per second - if writeback_percent is nonzero, background
480 writeback is throttled to this rate. Continuously adjusted by bcache but may
481 also be set by the user.
482
483 writeback_running
484 If off, writeback of dirty data will not take place at all. Dirty data will
485 still be added to the cache until it is mostly full; only meant for
486 benchmarking. Defaults to on.
487
488 Sysfs - backing device stats
489 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
490
491 There are directories with these numbers for a running total, as well as
492 versions that decay over the past day, hour and 5 minutes; they're also
493 aggregated in the cache set directory as well.
494
495 bypassed
496 Amount of IO (both reads and writes) that has bypassed the cache
497
498 cache_hits, cache_misses, cache_hit_ratio
499 Hits and misses are counted per individual IO as bcache sees them; a
500 partial hit is counted as a miss.
501
502 cache_bypass_hits, cache_bypass_misses
503 Hits and misses for IO that is intended to skip the cache are still counted,
504 but broken out here.
505
506 cache_miss_collisions
507 Counts instances where data was going to be inserted into the cache from a
508 cache miss, but raced with a write and data was already present (usually 0
509 since the synchronization for cache misses was rewritten)
510
511 Sysfs - cache set
512 ~~~~~~~~~~~~~~~~~
513
514 Available at /sys/fs/bcache/<cset-uuid>
515
516 average_key_size
517 Average data per key in the btree.
518
519 bdev<0..n>
520 Symlink to each of the attached backing devices.
521
522 block_size
523 Block size of the cache devices.
524
525 btree_cache_size
526 Amount of memory currently used by the btree cache
527
528 bucket_size
529 Size of buckets
530
531 cache<0..n>
532 Symlink to each of the cache devices comprising this cache set.
533
534 cache_available_percent
535 Percentage of cache device which doesn't contain dirty data, and could
536 potentially be used for writeback. This doesn't mean this space isn't used
537 for clean cached data; the unused statistic (in priority_stats) is typically
538 much lower.
539
540 clear_stats
541 Clears the statistics associated with this cache
542
543 dirty_data
544 Amount of dirty data is in the cache (updated when garbage collection runs).
545
546 flash_vol_create
547 Echoing a size to this file (in human readable units, k/M/G) creates a thinly
548 provisioned volume backed by the cache set.
549
550 io_error_halflife, io_error_limit
551 These determines how many errors we accept before disabling the cache.
552 Each error is decayed by the half life (in # ios). If the decaying count
553 reaches io_error_limit dirty data is written out and the cache is disabled.
554
555 journal_delay_ms
556 Journal writes will delay for up to this many milliseconds, unless a cache
557 flush happens sooner. Defaults to 100.
558
559 root_usage_percent
560 Percentage of the root btree node in use. If this gets too high the node
561 will split, increasing the tree depth.
562
563 stop
564 Write to this file to shut down the cache set - waits until all attached
565 backing devices have been shut down.
566
567 tree_depth
568 Depth of the btree (A single node btree has depth 0).
569
570 unregister
571 Detaches all backing devices and closes the cache devices; if dirty data is
572 present it will disable writeback caching and wait for it to be flushed.
573
574 Sysfs - cache set internal
575 ~~~~~~~~~~~~~~~~~~~~~~~~~~
576
577 This directory also exposes timings for a number of internal operations, with
578 separate files for average duration, average frequency, last occurrence and max
579 duration: garbage collection, btree read, btree node sorts and btree splits.
580
581 active_journal_entries
582 Number of journal entries that are newer than the index.
583
584 btree_nodes
585 Total nodes in the btree.
586
587 btree_used_percent
588 Average fraction of btree in use.
589
590 bset_tree_stats
591 Statistics about the auxiliary search trees
592
593 btree_cache_max_chain
594 Longest chain in the btree node cache's hash table
595
596 cache_read_races
597 Counts instances where while data was being read from the cache, the bucket
598 was reused and invalidated - i.e. where the pointer was stale after the read
599 completed. When this occurs the data is reread from the backing device.
600
601 trigger_gc
602 Writing to this file forces garbage collection to run.
603
604 Sysfs - Cache device
605 ~~~~~~~~~~~~~~~~~~~~
606
607 Available at /sys/block/<cdev>/bcache
608
609 block_size
610 Minimum granularity of writes - should match hardware sector size.
611
612 btree_written
613 Sum of all btree writes, in (kilo/mega/giga) bytes
614
615 bucket_size
616 Size of buckets
617
618 cache_replacement_policy
619 One of either lru, fifo or random.
620
621 discard
622 Boolean; if on a discard/TRIM will be issued to each bucket before it is
623 reused. Defaults to off, since SATA TRIM is an unqueued command (and thus
624 slow).
625
626 freelist_percent
627 Size of the freelist as a percentage of nbuckets. Can be written to to
628 increase the number of buckets kept on the freelist, which lets you
629 artificially reduce the size of the cache at runtime. Mostly for testing
630 purposes (i.e. testing how different size caches affect your hit rate), but
631 since buckets are discarded when they move on to the freelist will also make
632 the SSD's garbage collection easier by effectively giving it more reserved
633 space.
634
635 io_errors
636 Number of errors that have occurred, decayed by io_error_halflife.
637
638 metadata_written
639 Sum of all non data writes (btree writes and all other metadata).
640
641 nbuckets
642 Total buckets in this cache
643
644 priority_stats
645 Statistics about how recently data in the cache has been accessed.
646 This can reveal your working set size. Unused is the percentage of
647 the cache that doesn't contain any data. Metadata is bcache's
648 metadata overhead. Average is the average priority of cache buckets.
649 Next is a list of quantiles with the priority threshold of each.
650
651 written
652 Sum of all data that has been written to the cache; comparison with
653 btree_written gives the amount of write inflation in bcache.
654

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Bcache 설계와 초기 설정

1-97

Bcache는 큰 저속 RAID 6 같은 backing storage 앞에 SSD 하나 이상을 block-layer cache로 사용하는 기능입니다. Wiki는 `https://bcache.evilpiepirate.org`, bcache-tools repository는 `https://git.kernel.org/pub/scm/linux/kernel/git/colyli/bcache-tools.git/`, 최신 kernel code는 mainline Linux repository `https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/`에서 확인합니다.

설계는 SSD 성능 특성에 맞춥니다. Erase-block 크기의 bucket으로만 공간을 할당하고 hybrid btree/log로 한 sector부터 bucket 크기까지의 cached extent를 추적합니다. Random write를 피하기 위해 erase block을 순차적으로 채우고 재사용 전 discard를 발행합니다.

Writethrough와 writeback caching을 모두 지원합니다. Writeback은 기본적으로 꺼져 있지만 runtime에 자유롭게 전환할 수 있습니다. Bcache는 write가 stable storage에 도달하기 전에는 완료로 반환하지 않으므로 별도의 clean-shutdown 개념 없이도 unclean shutdown을 견디도록 data를 보호합니다.

Writeback은 cache 대부분을 write buffer로 쓸 수 있고, dirty data는 index 처음부터 끝까지 scan하며 backing device에 항상 순차적으로 기록합니다.

SSD가 잘 처리하는 것은 random I/O이므로 큰 sequential I/O를 cache해도 보통 이점이 적습니다. Bcache는 sequential I/O를 감지해 건너뛰고 task별 I/O size의 rolling average도 유지합니다. 평균이 cutoff보다 크면 seek 뒤 첫 512K만 cache하는 대신 해당 task의 모든 I/O를 건너뜁니다. 따라서 backup과 큰 file copy는 cache를 완전히 우회해야 합니다.

Flash의 data I/O error가 발생하면 disk에서 다시 읽거나 cache entry를 invalidate해 복구를 시도합니다. Metadata 또는 dirty data의 복구 불가능한 error에서는 caching을 자동으로 disable합니다. Dirty data가 있으면 먼저 writeback caching을 끄고 모두 flush될 때까지 기다립니다.

Bcache I/O policy
SituationBcache behavior
WritethroughComplete with backing storage updated
WritebackBuffer dirty writes in cache and flush sequentially
Large sequential I/ODetect and bypass cache
Random I/OUse SSD cache where it has the greatest benefit
Recoverable flash data errorRetry from disk or invalidate cache entry
Unrecoverable metadata/dirty-data errorDisable caching after flushing dirty data when possible

Cache mode와 workload 특성에 따른 핵심 동작입니다.

Bcache allocation lifecycle
Allocate erase-block-sized bucketFill sequentiallyTrack extents in hybrid btree/logIssue discardReuse bucket

SSD erase-block 특성에 맞춘 cache bucket 재사용 흐름입니다.

시작하려면 bcache-tools의 utility가 필요합니다. Backing device는 `-B`, cache device는 `-C`로 format합니다.

  bcache make -B /dev/sdb
  bcache make -C /dev/sdc

`bcache make` has the ability to format multiple devices at the same time - if
you format your backing devices and cache device at the same time, you won't
have to manually attach::

  bcache make -B /dev/sda /dev/sdb -C /dev/sdc

`bcache make`는 여러 device를 동시에 format할 수 있습니다. Backing과 cache device를 한 번에 format하면 수동 attach가 필요 없습니다. 오래된 bcache-tools에 unified `bcache` utility가 없다면 legacy `make-bcache`에서 같은 `-B`, `-C` parameter를 사용합니다.

최신 bcache-tools는 udev rule을 제공하므로 device를 kernel이 즉시 인식합니다. Udev가 없으면 다음처럼 직접 register합니다.

  echo /dev/sdb > /sys/fs/bcache/register
  echo /dev/sdc > /sys/fs/bcache/register

Backing device를 register하면 `/dev/bcache<N>` device가 나타나며 format하고 일반 block device처럼 쓸 수 있습니다. 새 bcache device는 cache에 attach하기 전까지 passthrough mode로 실행됩니다. 나중에 bcache를 쓸 계획이라면 저속 device를 cache 없이 bcache backing device로 먼저 설정하고 cache device는 이후 추가하는 방법을 권장합니다.

Udev가 있으면 UUID와 label alias도 만들며, ext4 format과 mount 예제 및 제어 path는 다음과 같습니다.

The devices show up as::

  /dev/bcache<N>

As well as (with udev)::

  /dev/bcache/by-uuid/<uuid>
  /dev/bcache/by-label/<label>

To get started::

  mkfs.ext4 /dev/bcache0
  mount /dev/bcache0 /mnt

You can control bcache devices through sysfs at /sys/block/bcache<N>/bcache .
You can also control them through /sys/fs//bcache/<cset-uuid>/ .

Cache devices are managed as sets; multiple caches per set isn't supported yet
but will allow for mirroring of metadata and dirty data in the future. Your new
cache set shows up as /sys/fs/bcache/<UUID>

Device별 제어는 `/sys/block/bcache<N>/bcache`, cache set 제어는 `/sys/fs//bcache/<cset-uuid>/`에서 합니다. Cache device는 set 단위로 관리합니다. Set당 cache 여러 개는 아직 지원하지 않지만 향후 metadata와 dirty data mirroring에 사용할 예정입니다.

Backing device를 cache set에 attach

98-126

Cache와 backing device를 register한 뒤 caching을 활성화하려면 backing device를 cache set에 attach합니다. `/sys/fs/bcache`에서 cache-set UUID를 찾아 다음처럼 씁니다.

After your cache device and backing device are registered, the backing device
must be attached to your cache set to enable caching. Attaching a backing
device to a cache set is done thusly, with the UUID of the cache set in
/sys/fs/bcache::

  echo <CSET-UUID> > /sys/block/bcache0/bcache/attach

Attach는 한 번만 하면 됩니다. 다음 reboot에서는 모든 bcache device를 다시 register하면 됩니다. Backing device data가 어떤 cache에 있으면 해당 cache가 나타날 때까지 `/dev/bcache<N>`을 만들지 않습니다. Writeback caching에서는 특히 중요합니다.

Boot 시 cache device가 사라졌고 돌아오지 않을 것이 확실하면 backing device를 강제로 실행할 수 있습니다.

If you're booting up and your cache device is gone and never coming back, you
can force run the backing device::

  echo 1 > /sys/block/sdb/bcache/running

(You need to use /sys/block/sdb (or whatever your backing device is called), not
/sys/block/bcache0, because bcache0 doesn't exist yet. If you're using a
partition, the bcache directory would be at /sys/block/sdb/sdb2/bcache)

`/sys/block/bcache0`은 아직 존재하지 않으므로 `/sys/block/sdb/bcache/running` 같은 실제 backing-device path를 사용합니다. Partition이면 예를 들어 `/sys/block/sdb/sdb2/bcache`입니다.

Backing device는 cache set이 나중에 나타나면 다시 사용하지만 cached data는 모두 invalidate됩니다. Cache에 dirty data가 있었다면 filesystem은 대규모 corruption이 생길 수 있어 복구를 기대해서는 안 됩니다. 다만 ext4 `fsck`가 상당 부분 복구할 수는 있습니다.

Attach and missing-cache paths
Register backing and cacheWrite CSET-UUID to attachCreate /dev/bcacheNCache data safely
Cache permanently missingWrite 1 to backing-device runningInvalidate cached dataRisk corruption if dirty data existed

정상 attach와 cache 영구 손실 시 강제 실행의 차이입니다.

Cache-device I/O error 처리

127-150

Bcache는 정상 동작에 영향을 주지 않도록 cache device와의 I/O error를 투명하게 처리하려 합니다. Configurable threshold를 넘는 error를 관찰하면 cache device를 shut down하고 모든 backing device를 passthrough mode로 전환합니다. Threshold 기본값은 0입니다.

Bcache error handling matrix
OperationOn cache error
Cache readRetry read from backing device
Writethrough writeInvalidate cache data at that LBA
Writeback writeReturn error to filesystem/userspace
Detach in writebackTry to flush dirty data first
undefinedundefined
undefinedundefined

I/O 유형별 cache error 처리와 현재 한계입니다.

Cookbook: cache 손실과 data 복구

151-209

A) Cache device가 없는 bcache를 시작할 때 backing device register가 `device already registered`로 실패하면 이미 등록된 것입니다. Cache가 없거나 register에 실패해도 backing-device의 `running`에 1을 써서 cache 없이 시작할 수 있습니다. Writeback mode였다면 data loss가 생길 수 있습니다.

A) Starting a bcache with a missing caching device

If registering the backing device doesn't help, it's already there, you just need
to force it to run without the cache::

	host:~# echo /dev/sdb1 > /sys/fs/bcache/register
	[  119.844831] bcache: register_bcache() error opening /dev/sdb1: device already registered

Next, you try to register your caching device if it's present. However
if it's absent, or registration fails for some reason, you can still
start your bcache without its cache, like so::

	host:/sys/block/sdb/sdb1/bcache# echo 1 > running

Note that this may cause data loss if you were running in writeback mode.

B) Attach가 `cache set not found`로 실패하면 cache device가 boot 때 register되지 않았거나 사라졌다 돌아온 경우입니다. Cache device를 `/sys/fs/bcache/register`에 다시 씁니다.

B) Bcache does not find its cache::

	host:/sys/block/md5/bcache# echo 0226553a-37cf-41d5-b3ce-8b1e944543a8 > attach
	[ 1933.455082] bcache: bch_cached_dev_attach() Couldn't find uuid for md5 in set
	[ 1933.478179] bcache: __cached_dev_store() Can't attach 0226553a-37cf-41d5-b3ce-8b1e944543a8
	[ 1933.478179] : cache set not found

In this case, the caching device was simply not registered at boot
or disappeared and came back, and needs to be (re-)registered::

	host:/sys/block/md5/bcache# echo /dev/sdh2 > /sys/fs/bcache/register

C) 손상된 bcache가 device register 시 kernel crash를 일으키면 발생해서는 안 되는 bug입니다. Kernel `dmesg`를 포함해 가능한 많은 정보를 `linux-bcache@vger.kernel.org` development list에 보고합니다.

D) Kernel에서 bcache를 사용할 수 없어도 backing device의 filesystem은 기본 8 KiB offset에 남아 있습니다. Format 때 `bcache make --data-offset`으로 다른 값을 정했다면 그 offset을 사용합니다. `--offset 8K` loop device 또는 다음 command로 원본 backing data를 `/dev/loop0`에 노출합니다.

D) Recovering data without bcache:

If bcache is not available in the kernel, a filesystem on the backing
device is still available at an 8KiB offset. So either via a loopdev
of the backing device created with --offset 8K, or any value defined by
--data-offset when you originally formatted bcache with `bcache make`.

For example::

	losetup -o 8192 /dev/loop0 /dev/your_bcache_backing_dev

This should present your unmodified backing device data in /dev/loop0

Cache가 writethrough mode라면 data loss 없이 cache device를 버려도 안전합니다.

Missing-cache recovery cases
CaseActionRisk/result
Backing already registeredWrite 1 to backing bcache/runningWriteback dirty data may be lost
Cache set not foundRe-register cache deviceAttach can proceed
Registration crashes kernelReport with dmesg to linux-bcache@vger.kernel.orgTreat as kernel bug
Kernel lacks bcacheExpose backing data with loop offsetFilesystem starts at configured data offset

Cookbook A-D의 증상과 조치를 요약합니다.

Cookbook: cache 교체·stack 해제

210-316

E) Cache device를 wipe하려면 `wipefs -a`로 bcache signature를 지웁니다. Bcache를 다시 활성화한 뒤 cache를 `bcache make -C`로 재생성하고, cache가 없는 backing device를 `running`으로 시작한 다음 새 Set UUID를 `attach`에 씁니다.

E) Wiping a cache device

::

	host:~# wipefs -a /dev/sdh2
	16 bytes were erased at offset 0x1018 (bcache)
	they were: c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81

After you boot back with bcache enabled, you recreate the cache and attach it::

	host:~# bcache make -C /dev/sdh2
	UUID:                   7be7e175-8f4c-4f99-94b2-9c904d227045
	Set UUID:               5bc072a8-ab17-446d-9744-e247949913c1
	version:                0
	nbuckets:               106874
	block_size:             1
	bucket_size:            1024
	nr_in_set:              1
	nr_this_dev:            0
	first_bucket:           1
	[  650.511912] bcache: run_cache_set() invalidating existing data
	[  650.549228] bcache: register_cache() registered cache device sdh2

start backing device with missing cache::

	host:/sys/block/md5/bcache# echo 1 > running

attach new cache::

	host:/sys/block/md5/bcache# echo 5bc072a8-ab17-446d-9744-e247949913c1 > attach
	[  865.276616] bcache: bch_cached_dev_attach() Caching md5 as bcache0 on set 5bc072a8-ab17-446d-9744-e247949913c1

F) Cache device를 제거·교체할 때는 backing device에서 먼저 `detach`합니다. Disable만 하고 unregister하지 않으면 device가 busy로 보호돼 `wipefs`가 실패합니다. Cache-set directory의 `stop`에 1을 써서 unregister한 뒤 wipe할 수 있습니다.

F) Remove or replace a caching device::

	host:/sys/block/sda/sda7/bcache# echo 1 > detach
	[  695.872542] bcache: cached_dev_detach_finish() Caching disabled for sda7

	host:~# wipefs -a /dev/nvme0n1p4
	wipefs: error: /dev/nvme0n1p4: probing initialization failed: Device or resource busy
	Ooops, it's disabled, but not unregistered, so it's still protected

We need to go and unregister it::

	host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# ls -l cache0
	lrwxrwxrwx 1 root root 0 Feb 25 18:33 cache0 -> ../../../devices/pci0000:00/0000:00:1d.0/0000:70:00.0/nvme/nvme0/nvme0n1/nvme0n1p4/bcache/
	host:/sys/fs/bcache/b7ba27a1-2398-4649-8ae3-0959f57ba128# echo 1 > stop
	kernel: [  917.041908] bcache: cache_set_free() Cache set b7ba27a1-2398-4649-8ae3-0959f57ba128 unregistered

Now we can wipe it::

	host:~# wipefs -a /dev/nvme0n1p4
	/dev/nvme0n1p4: 16 bytes were erased at offset 0x00001018 (bcache): c6 85 73 f6 4e 1a 45 ca 82 65 f5 7f 48 ba 6d 81

G) dm-crypt와 bcache를 함께 쓸 때는 먼저 unencrypted bcache를 만들고 `/dev/bcache<N>` 위에 dm-crypt를 설치합니다. Backing과 cache device를 각각 encrypt한 뒤 그 위에 bcache를 두는 것보다 빠릅니다.

H) Partition table을 바꿔 fdisk하고 다시 register하려면 모든 bcache reference를 해제해야 합니다. `/dev/bcache*`가 존재하면 `/sys/block/bcache0/bcache/stop`에 1을 씁니다. Backing device가 사라져 이 path가 없으면 bcache를 참조하는 dm-crypt block device를 `dmsetup remove`로 제거합니다. Bcache가 다른 stacked block device의 하위 device인 경우도 같은 원리입니다.

그 밖에는 `/sys/fs/bcache/` 아래 `cache?`, `bdev?` symlink를 조사해 관련 UUID directory를 찾고 그 directory의 `stop`에 1을 씁니다. 그러면 bcache reference가 해제돼 partition을 다른 목적으로 재사용할 수 있습니다.

H) Stop/free a registered bcache to wipe and/or recreate it

Suppose that you need to free up all bcache references so that you can
fdisk run and re-register a changed partition table, which won't work
if there are any active backing or caching devices left on it:

1) Is it present in /dev/bcache* ? (there are times where it won't be)

   If so, it's easy::

	host:/sys/block/bcache0/bcache# echo 1 > stop

2) But if your backing device is gone, this won't work::

	host:/sys/block/bcache0# cd bcache
	bash: cd: bcache: No such file or directory

   In this case, you may have to unregister the dmcrypt block device that
   references this bcache to free it up::

	host:~# dmsetup remove oldds1
	bcache: bcache_device_free() bcache0 stopped
	bcache: cache_set_free() Cache set 5bc072a8-ab17-446d-9744-e247949913c1 unregistered

   This causes the backing bcache to be removed from /sys/fs/bcache and
   then it can be reused.  This would be true of any block device stacking
   where bcache is a lower device.

3) In other cases, you can also look in /sys/fs/bcache/::

	host:/sys/fs/bcache# ls -l */{cache?,bdev?}
	lrwxrwxrwx 1 root root 0 Mar  5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/bdev1 -> ../../../devices/virtual/block/dm-1/bcache/
	lrwxrwxrwx 1 root root 0 Mar  5 09:39 0226553a-37cf-41d5-b3ce-8b1e944543a8/cache0 -> ../../../devices/virtual/block/dm-4/bcache/
	lrwxrwxrwx 1 root root 0 Mar  5 09:39 5bc072a8-ab17-446d-9744-e247949913c1/cache0 -> ../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0/ata10/host9/target9:0:0/9:0:0:0/block/sdl/sdl2/bcache/

   The device names will show which UUID is relevant, cd in that directory
   and stop the cache::

	host:/sys/fs/bcache/5bc072a8-ab17-446d-9744-e247949913c1# echo 1 > stop

   This will free up bcache references and let you reuse the partition for
   other purposes.
Safely replace a cache device
Detach backing deviceFlush dirty dataStop cache setUnregister cache devicewipefs or replace deviceCreate and attach new cache

Disable만으로는 device가 보호되므로 detach와 unregister를 모두 수행합니다.

Reference-release paths
Observed stateRelease action
/dev/bcacheN existsWrite 1 to /sys/block/bcacheN/bcache/stop
Backing path gone, dm-crypt references bcachedmsetup remove <mapping>
Only cache-set symlinks identify deviceFind UUID under /sys/fs/bcache and write 1 to stop

현재 block-device stack에 따라 stop 위치가 달라집니다.

성능 문제 진단과 benchmark tuning

317-402

Bcache 기본 config와 tunable은 일반 desktop·server workload에 합리적으로 맞춰져 있지만 benchmark 최고 수치에는 적합하지 않을 수 있습니다.

Backing device alignment: 기본 metadata 크기는 8 KiB입니다. RAID backing device라면 `bcache make --data-offset`으로 stride width의 배수에 맞춥니다. 향후 array 확장을 고려하면 RAID stripe size에 prime series를 곱해 원하는 disk count의 공배수 offset을 만듭니다. 64 KiB stripe에서 `64k * 2*2*2*3*3*5*7 = 161280k`를 쓰면 약 157.5 MB를 희생해 3,4,5,6,7,8,9,10,12,14,15,18,20,21 등의 RAID5 data-spindle count에 alignment를 유지할 수 있습니다.

 - Backing device alignment

   The default metadata size in bcache is 8k.  If your backing device is
   RAID based, then be sure to align this by a multiple of your stride
   width using `bcache make --data-offset`. If you intend to expand your
   disk array in the future, then multiply a series of primes by your
   raid stripe size to get the disk multiples that you would like.

   For example:  If you have a 64k stripe size, then the following offset
   would provide alignment for many common RAID5 data spindle counts::

	64k * 2*2*2*3*3*5*7 bytes = 161280k

   That space is wasted, but for only 157.5MB you can grow your RAID 5
   volume to the following data-spindle counts without re-aligning::

	3,4,5,6,7,8,9,10,12,14,15,18,20,21 ...

Write 성능이 기대보다 낮다면 기본값이 아닌 writeback mode가 필요할 수 있습니다. Writeback이 기본값이 아닌 이유는 미성숙해서가 아니라 SSD 문제 시 data를 잃을 수 있기 때문입니다.

 - Bad write performance

   If write performance is not what you expected, you probably wanted to be
   running in writeback mode, which isn't the default (not due to a lack of
   maturity, but simply because in writeback mode you'll lose data if something
   happens to your SSD)::

	# echo writeback > /sys/block/bcache0/bcache/cache_mode

SSD로 갈 것으로 예상한 traffic이 가지 않으면 sequential bypass 때문일 수 있습니다. 10 GB sequential copy가 random working set 10 GB를 밀어내지 않도록 기본적으로 모든 I/O를 cache하지 않습니다. Fio가 8 GB test file을 먼저 쓰는 read-cache benchmark에서는 `sequential_cutoff`을 0으로 끄고, 끝나면 기본 4 MB로 복원합니다.

 - Bad performance, or traffic not going to the SSD that you'd expect

   By default, bcache doesn't cache everything. It tries to skip sequential IO -
   because you really want to be caching the random IO, and if you copy a 10
   gigabyte file you probably don't want that pushing 10 gigabytes of randomly
   accessed data out of your cache.

   But if you want to benchmark reads from cache, and you start out with fio
   writing an 8 gigabyte test file - so you want to disable that::

	# echo 0 > /sys/block/bcache0/bcache/sequential_cutoff

   To set it back to the default (4 mb), do::

	# echo 4M > /sys/block/bcache0/bcache/sequential_cutoff

계속 spindle traffic이나 cache miss가 발생할 수 있습니다. 느린 SSD, SSD 하나가 disk 여러 개를 cache하는 구성, 대부분 sequential인 I/O에서는 SSD가 disk를 따라가지 못할 수 있습니다. Bcache는 cache-device latency를 추적하고 threshold를 넘으면 sequential bypass를 높여 traffic을 점진적으로 throttle합니다. 필요하면 read/write threshold를 0으로 설정해 비활성화합니다. 기본값은 read 2000 us(2 ms), write 20000 us입니다.

 - Traffic's still going to the spindle/still getting cache misses

   In the real world, SSDs don't always keep up with disks - particularly with
   slower SSDs, many disks being cached by one SSD, or mostly sequential IO. So
   you want to avoid being bottlenecked by the SSD and having it slow everything
   down.

   To avoid that bcache tracks latency to the cache device, and gradually
   throttles traffic if the latency exceeds a threshold (it does this by
   cranking down the sequential bypass).

   You can disable this if you need to by setting the thresholds to 0::

	# echo 0 > /sys/fs/bcache/<cache set>/congested_read_threshold_us
	# echo 0 > /sys/fs/bcache/<cache set>/congested_write_threshold_us

   The default is 2000 us (2 milliseconds) for reads, and 20000 for writes.

같은 data에서 계속 cache miss가 나는 마지막 원인은 cache coherency 처리의 오래된 bug일 수 있습니다. Btree node가 가득 차면 cache miss가 새 data key를 삽입하지 못해 cache에 쓰지 못합니다. 일반 workload에서는 write 하나가 node split을 유발해 거의 문제가 없지만, 다른 traffic 없이 read로만 cache를 warm-up하는 benchmark에서는 드러날 수 있습니다. Write로 warm-up하거나 fix가 있는 testing branch를 사용합니다.

Bcache performance checklist
SymptomActionDefault/risk
RAID misalignmentSet --data-offset to stride multipleMetadata starts at 8 KiB by default
Slow writesSet cache_mode=writebackSSD failure can lose dirty data
Sequential benchmark bypasses cacheSet sequential_cutoff=0Restore to 4M
SSD latency throttles trafficSet congestion thresholds to 0 for testRead 2000 us, write 20000 us
Read-only warmup misses repeatedlyWarm with writes or use testing fixFull btree node cannot insert miss key

증상별 확인할 설정과 원문 기본값입니다.

Backing-device sysfs

403-487

Backing-device attribute는 `/sys/block/<bdev>/bcache`, `/sys/block/bcache*/bcache`, attach된 경우 `/sys/fs/bcache/<cset-uuid>/bdev*`에서 제공합니다.

Backing-device attributes
AttributeMeaning
attachCache-set UUID를 써서 caching 활성화
cache_modewritethrough, writeback, writearound 또는 none
clear_statsRunning-total 통계 reset; day/hour/5-minute decay 통계는 유지
detachCache set에서 분리; dirty data를 먼저 flush
dirty_data이 backing device의 cache 내 dirty data 양; 지속 갱신되지만 약간 부정확할 수 있음
labelUnderlying device 이름
readaheadCache-miss read를 기존 entry와 겹치지 않게 올림; 기본 0, 예: 1M
running/dev/bcache device가 존재하며 passthrough 또는 caching 중이면 1
sequential_cutoff최근 128 I/O로 sequential stream을 추적하고 threshold 이후 cache 우회
sequential_merge최근 128 request와 새 request를 비교해 sequential continuation 판정
stateno cache, clean, dirty 또는 inconsistent
stopBcache device를 shut down하고 backing device close
writeback_delay첫 dirty data 뒤 writeback 시작 전 대기 seconds; 기본 30
writeback_percentPD controller로 cache의 목표 dirty percentage 유지
writeback_rateBackground writeback sectors/second; bcache와 사용자가 조정 가능
writeback_runningOff면 dirty data writeback 전면 중지; benchmark 전용, 기본 on

Attach, mode, state, sequential detection과 writeback 제어입니다.

Backing-device states
StateMeaning
no cacheCache set에 attach된 적 없음
cleanCache set 소속이며 cached dirty data 없음
dirtyCache set 소속이며 cached dirty data 있음
inconsistentCache set 부재 중 dirty cache를 무시하고 강제 실행해 backing data가 손상됐을 가능성이 큼

Cache association과 dirty-data 상태를 구분합니다.

`sequential_merge`는 한 request의 최대 허용 sequential size보다 `sequential_cutoff`이 큰 경우 필요합니다. `writeback_percent`가 0이 아니면 PD controller가 background writeback을 throttle하며 `writeback_rate`를 지속 조정합니다. `writeback_running=off`에서도 cache가 거의 찰 때까지 dirty data는 계속 추가되므로 benchmark 외에는 사용하지 않습니다.

Backing-device 통계

488-510

통계 directory는 running total과 지난 day, hour, 5 minutes에 걸쳐 decay하는 version을 제공합니다. Cache-set directory에도 aggregate됩니다.

Backing-device statistics
StatisticMeaning
bypassedCache를 우회한 read와 write I/O 양
cache_hitsBcache가 본 개별 I/O 단위 cache hit
cache_misses개별 I/O miss; partial hit도 miss로 계산
cache_hit_ratioHit와 miss의 비율
cache_bypass_hitsCache를 건너뛰려던 I/O의 hit
cache_bypass_missesCache를 건너뛰려던 I/O의 miss
cache_miss_collisionsMiss insert가 write와 race해 data가 이미 존재한 횟수; 보통 0

Cache 우회·hit/miss와 miss-insert race를 측정합니다.

Cache-set sysfs

511-573

Cache-set attribute는 `/sys/fs/bcache/<cset-uuid>`에서 제공합니다.

Cache-set attributes
AttributeMeaning
average_key_sizeBtree key당 평균 data
bdev<0..n>Attach된 backing device 각각의 symlink
block_sizeCache device block size
btree_cache_sizeBtree cache가 현재 사용하는 memory
bucket_sizeBucket size
cache<0..n>Cache set을 구성하는 cache device symlink
cache_available_percentDirty data가 없어 writeback에 쓸 수 있는 cache percentage
clear_stats이 cache와 관련된 통계 clear
dirty_dataCache의 dirty data 양; garbage collection 때 갱신
flash_vol_createk/M/G 단위 size를 써서 thin-provisioned cache-backed volume 생성
io_error_halflifeError count를 I/O 횟수에 따라 decay시키는 half-life
io_error_limitDecay count가 도달하면 dirty data를 쓰고 cache disable
journal_delay_msFlush가 먼저 오지 않으면 journal write를 지연할 최대 ms; 기본 100
root_usage_percentRoot btree node 사용률; 높아지면 split되어 tree depth 증가
stop모든 attached backing device가 종료될 때까지 기다린 뒤 cache set shut down
tree_depthBtree depth; single-node tree는 0
unregister모든 backing device detach 및 cache close; dirty data flush까지 대기
undefinedundefined

Btree geometry, device link, error policy, journal과 set lifecycle입니다.

I/O error decay policy
Observe cache I/O errorAdd to decaying countDecay over io_error_halflife I/OsReach io_error_limitWrite out dirty dataDisable cache

Error count가 half-life로 줄어들면서도 limit에 닿으면 cache를 안전하게 중지합니다.

Cache-set 내부 통계

574-603

이 directory는 garbage collection, btree read, btree-node sort와 btree split의 내부 timing도 제공합니다. 각 operation마다 average duration, average frequency, last occurrence, maximum duration file이 따로 있습니다.

Cache-set internal attributes
AttributeMeaning
active_journal_entriesIndex보다 새로운 journal entry 수
btree_nodesBtree의 전체 node 수
btree_used_percentBtree 평균 사용 fraction
bset_tree_statsAuxiliary search tree 통계
btree_cache_max_chainBtree-node cache hash table의 최장 chain
cache_read_racesCache read 중 bucket이 재사용·invalidate돼 stale pointer가 된 횟수
trigger_gcWrite하여 garbage collection 강제 실행

Journal, btree 구조, race와 수동 garbage collection을 관찰합니다.

`cache_read_races`가 발생하면 cache에서 읽은 data를 버리고 backing device에서 다시 읽습니다.

Cache-device sysfs

604-653

Cache-device attribute는 `/sys/block/<cdev>/bcache`에서 제공합니다.

Cache-device attributes
AttributeMeaning
block_size최소 write granularity; hardware sector size와 일치해야 함
btree_written모든 btree write 합계, k/M/G bytes
bucket_sizeBucket size
cache_replacement_policylru, fifo 또는 random
discardBucket 재사용 전 discard/TRIM; 기본 off
freelist_percentnbuckets 대비 freelist percentage; runtime cache size 축소 가능
io_errorsio_error_halflife로 decay한 error 수
metadata_writtenBtree와 기타 metadata write 합계
nbuckets이 cache의 전체 bucket 수
priority_statsAccess recency, unused, metadata overhead, average priority와 quantile
writtenCache에 쓴 전체 data 합계
undefinedundefined
undefinedundefined
undefinedundefined

Cache geometry, replacement, discard, error와 write-volume 통계입니다.

`priority_stats`의 `Unused`는 data가 없는 cache percentage, `Metadata`는 bcache metadata overhead, `Average`는 cache-bucket 평균 priority입니다. 그 뒤에는 각 quantile의 priority threshold 목록이 이어집니다.

Cache-device write accounting
Track written dataTrack btree_written metadataCompare countersEstimate bcache write inflation

Data와 btree write counter의 차이로 write amplification을 관찰합니다.