1. 程式人生 > 實用技巧 >Cgroup核心文件翻譯(2)——Documentation/cgroup-v1/blkio-controller.txt

Cgroup核心文件翻譯(2)——Documentation/cgroup-v1/blkio-controller.txt

Block IO Controller
===================

總覽
========
cgroup子系統 "blkio" 實現了塊io控制器。 在儲存層次結構中的葉節點以及中間節點處似乎都需要各種型別的IO控制策略(如比例BW,最大BW)。 計劃是將相同的基於cgroup的管理介面用於blkio控制器,並根據使用者選項在後臺切換IO策略。

當前,已實施兩種IO控制策略。 第一個是基於比例權重時間的磁碟策略劃分。 它在CFQ中實現。 因此,當使用CFQ時,此策略僅對葉節點有效。 第二個是限制策略,可用於指定裝置上的IO速率上限。 該策略在通用塊層中實現,可以在葉節點以及更高級別的邏輯裝置(例如裝置對映器)上使用。


如何做
=====
頻寬比例權重劃分
-----------------------------------------
您可以對在兩個不同的cgroup中執行兩個dd執行緒進行非常簡單的測試。 這是您可以做的。

-啟用塊IO控制器
    CONFIG_BLK_CGROUP = y

-在CFQ中啟用組排程
    CONFIG_CFQ_GROUP_IOSCHED = y

-編譯並在核心中啟動,並掛載IO控制器(blkio); 請參閱cgroups.txt,為什麼需要cgroup ?。
    mount -t tmpfs cgroup_root /sys/fs/cgroup
    mkdir /sys/fs/cgroup/blkio
    mount 
-t cgroup -o blkio none /sys/fs/cgroup/blkio -建立兩個cgroup mkdir -p /sys/fs/cgroup/blkio/test1/ /sys/fs/cgroup/blkio/test2 -設定組test1和test2的權重 echo 1000 > /sys/fs/cgroup/blkio/test1/blkio.weight echo 500 > /sys/fs/cgroup/blkio/test2/blkio.weight -在同一磁碟上建立兩個大小相同的檔案(檔案1,檔案2,每個檔案512 MB),並在不同的cgroup中啟動兩個dd執行緒去讀取這些檔案。 sync echo
3 > /proc/sys/vm/drop_caches dd if=/mnt/sdb/zerofile1 of=/dev/null & echo $! > /sys/fs/cgroup/blkio/test1/tasks cat /sys/fs/cgroup/blkio/test1/tasks dd if=/mnt/sdb/zerofile2 of=/dev/null & echo $! > /sys/fs/cgroup/blkio/test2/tasks cat /sys/fs/cgroup/blkio/test2/tasks

-在巨集級別,第一個dd應該先完成。 為了獲得更精確的資料,請繼續(藉助指令碼)檢視 test1 和 test2 組的 blkio.disk_time和 blkio.disk_sectors 檔案。 這將告訴每個組獲得了多少磁碟時間(以毫秒為單位),每個組向磁碟派發了多少個扇區。 我們提供磁碟時間方面的公平性,因此理想情況下 cgroups 的 io.disk_time 應該與權重成比例。

節流/上限策略
-----------------------------

-啟用塊IO控制器
    CONFIG_BLK_CGROUP=y

-在塊層啟用節流
    CONFIG_BLK_DEV_THROTTLING=y

-掛載blkio控制器(請參閱cgroups.txt,為什麼需要cgroup?)
    mount -t cgroup -o blkio none /sys/fs/cgroup/blkio

-在特定裝置上為根組指定頻寬速率。 策略的格式為 "<major>:<minor>  <bytes_per_second>".
    echo "8:16  1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device

上面將對 major/minor裝置號為8:16的裝置上的根組的讀取速度限制為1MB/秒。

-執行dd讀取檔案,然後檢視速率是否已限制為1MB/s。

    # dd iflag=direct if=/mnt/common/zerofile of=/dev/null bs=4K count=1024
    1024+0 records in
    1024+0 records out
    4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s

可以使用 blkio.throttle.write_bps_device 檔案對寫入速率進行限制。

分層Cgroup
====================

CFQ和節流策略都實現了對層次結構的支援; 但是,如果從 cgroup 端啟用了“sane_behavior”,則啟用了節流的層次結構支援,
當前這是開發選項,並且不公開。

如果有人建立瞭如下的層次結構。

        root
        /  \
      test1 test2
        |
      test3

預設情況下,CFQ並使用“sane_behavior”進行限制將正確處理層次結構。 有關CFQ層次結構支援的詳細資訊,請參閱 Documentation/block/cfq-iosched.txt。 對於節流,所有限制都適用於整個子樹,而所有統計資訊對於該cgroup中的任務直接生成的IO都是本地的。

在沒有從cgroup端啟用“sane_behavior”的情況下,進行節流實際上會將所有組視為相同級別,就像以下所示。

           pivot
       /   /  \    \
    root test1 test2 test3

各種使用者可見的配置選項
==================================

CONFIG_BLK_CGROUP
    -塊IO控制器。

CONFIG_DEBUG_BLK_CGROUP
    -除錯幫助資訊。現在,如果啟用了此選項,則cgroup中會顯示一些其他統計資訊檔案。

CONFIG_CFQ_GROUP_IOSCHED
    -在CFQ中啟用組排程。 當前僅允許建立1級group。

CONFIG_BLK_DEV_THROTTLING
    -在塊層啟用塊裝置節流支援。

cgroup檔案的詳細資訊
=======================

比例權重策略檔案
--------------------------------

-blkio.weight
  -指定每個cgroup的權重。 這是所有裝置上該組的預設權重,直到且除非被每個裝置規則覆蓋。(請參閱 blkio.weight_device)。 當前允許的權重範圍是10到1000。

-blkio.weight_device
  -可以使用此介面為每個裝置的每個cgroup指定規則。這些規則將覆蓋 blkio.weight 指定的組權重的預設值。

      # echo dev_maj:dev_minor weight > blkio.weight_device
      Configure weight=300 on /dev/sdb (8:16) in this cgroup
      # echo 8:16 300 > blkio.weight_device
      # cat blkio.weight_device
      dev     weight
      8:16    300

      Configure weight=500 on /dev/sda (8:0) in this cgroup
      # echo 8:0 500 > blkio.weight_device
      # cat blkio.weight_device
      dev     weight
      8:0     500
      8:16    300

      Remove specific weight for /dev/sda in this cgroup
      # echo 8:0 0 > blkio.weight_device
      # cat blkio.weight_device
      dev     weight
      8:16    300

-blkio.leaf_weight[_device]
  -blkio.weight[_device]的等效項,用於決定與cgroup的子cgroup競爭時給定cgroup中任務的權重。 有關詳細資訊,請參閱 Documentation/block/cfq-iosched.txt.。

-blkio.time
  -每個裝置分配給cgroup的磁碟時間(以毫秒為單位)。 前兩個欄位指定裝置的主裝置號和次裝置號,第三個欄位指定分配給組的磁碟時間(以毫秒為單位)。

-blkio.sectors
  -此組從磁碟傳輸或接收的扇區數。前兩個欄位指定裝置的主裝置號和次裝置號,第三個欄位指定組向裝置/從裝置傳輸的扇區數。

-blkio.io_service_bytes
  -組從磁碟傳輸的或接收的位元組數。這些操作按操作型別進一步劃分-讀取或寫入,同步或非同步。 前兩個欄位指定裝置的主要和次要裝置號,第三個欄位指定操作型別,第四個欄位指定位元組數。

-blkio.io_serviced
  -該組向磁碟發出的IO(bio)數量。 這些操作按操作型別進一步劃分-讀取或寫入,同步或非同步。 前兩個欄位指定裝置的主次裝置號,第三個欄位指定操作型別,第四個欄位指定IO的數量。

-blkio.io_service_time
  -此cgroup完成的IO的請求分發和請求完成之間的總時間。 這在1ns內對快閃記憶體裝置也很有意義。 對於佇列深度為1的裝置,此時間表示實際服務時間。 當 queue_depth > 1時,這不再是正確的,因為可能會無序地處理請求。 這可能會導致給定IO的服務時間在無序提供時包括多個IO的服務時間,這可能導
致總 io_service_time > 實際時間。 該時間還可以通過操作型別進一步劃分-讀或寫,同步或非同步。 前兩個欄位指定裝置的主裝置號和次裝置號,第三個欄位指定操作型別,第四個欄位指定以ns為單位的io_service_time。

-blkio.io_wait_time
  -此cgroup的IO在排程程式佇列中等待服務的總時間。這可以大於所花費的總時間,因為它是所有IO的累積 io_wait_time。 它不是衡量 cgroup 等待總時間的方法,而是衡量各個IO的 wait_time 的方法。對於 queue_depth> 1的裝置,此指標不包括將IO分配給裝置後等待服務所花費的時間,但直到它得到實際服務為止(由於裝置對請求的重新排序,因此可能會有時間滯後)。 這在1ns內對快閃記憶體裝置也很有意義。 該時間還可以通過操作型別進一步劃分-讀或寫,同步或非同步。 前兩個欄位指定裝置的主裝置號和次裝置號,第三個欄位指定操作型別,第四個欄位指定以ns為單位的 io_wait_time。

-blkio.io_merged
  -合併到屬於此cgroup的請求的bios/requests總數。 這可以通過操作型別進一步劃分-讀或寫,同步或非同步。

-blkio.io_queued
  -在任何給定時刻為此cgroup排隊的請求總數。 這可以通過操作型別進一步劃分-讀或寫,同步或非同步。

-blkio.avg_queue_size
  -僅在 CONFIG_DEBUG_BLK_CGROUP = y 時啟用的除錯輔助。 在此cgroup存在的整個時間內,此cgroup的平均佇列大小。 每當此cgroup的佇列之一獲得時間片時,就對佇列大小進行取樣。

-blkio.group_wait_time
  -僅在 CONFIG_DEBUG_BLK_CGROUP = y 時啟用的除錯幫助資訊。 這是自從cgroup變得繁忙(即請求從0到1進入佇列)以來為其佇列之一獲取時間片所必須等待的時間。 這不同於 io_wait_time,它是該cgroup中每個IO在排程程式佇列中等待的時間的累積總數。以納秒為單位。 如果在cgroup處於等待(用於時間片)狀態時讀取此內容,則該統計資訊將僅報告直到其最後獲得時間片為止所累積的 group_wait_time,並且不包括當前增量。

-blkio.empty_time
  -僅在 CONFIG_DEBUG_BLK_CGROUP = y 時啟用除錯輔助資訊。 這是cgroup在沒有被服務時花費在沒有任何未決請求的情況下的時間,即,它不包括花費在cgroup佇列之一空閒上的任何時間。 以納秒為單位。 如果在cgroup處於空狀態時讀取了此內容,則該統計資訊將僅報告直到上一次有待處理請求為止所累積的empty_time,並且將不包括當前增量。

-blkio.idle_time
  -僅在 CONFIG_DEBUG_BLK_CGROUP = y 時啟用的除錯輔助資訊。 這是IO排程程式閒置給定cgroup所花費的時間,以期望比來自其他佇列/cgroup的現有請求更好的請求。 以納秒為單位。 如果在cgroup處於空閒狀態時讀取了此資訊,則該統計資訊將僅報告直到最後一個空閒時間段為止累積的idle_time,並且將不包括當前增量。

-blkio.dequeue
  -僅在 CONFIG_DEBUG_BLK_CGROUP = y時啟用除錯輔助資訊。這提供了有關組從裝置的服務樹中出隊多少次的統計資訊。 前兩個欄位指定裝置的主裝置號和次裝置號,第三個欄位指定組從特定裝置出隊的次數。

- blkio.*_recursive
  -各種統計資訊的遞迴版本。 這些檔案顯示與非遞迴對應檔案相同的資訊,但包括來自所有後代cgroup的統計資訊。

節流/上限策略檔案
-----------------------------------
-blkio.throttle.read_bps_device
  -指定裝置讀取速率的上限。IO速率以每秒位元組數指定。 規則是針對每個裝置的。 以下是格式。

echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.read_bps_device

-blkio.throttle.write_bps_device
  -指定寫入裝置的速率上限。 IO速率以每秒位元組數指定。 規則是針對每個裝置的。 以下是格式。

echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.write_bps_device

-blkio.throttle.read_iops_device
  -指定裝置讀取速率的上限。 IO速率以每秒IO為單位指定。 規則是針對每個裝置的。 以下是格式。

echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.read_iops_device

-blkio.throttle.write_iops_device
  -指定寫入裝置的速率上限。 IO速率以io每秒為單位指定。 規則是針對每個裝置的。 以下是格式。

echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.write_iops_device

注意:如果為裝置同時指定了BW和IOPS規則,則IO受到兩個約束。

-blkio.throttle.io_serviced
  -該組向磁碟發出的IO(bio)數量。 這些操作按操作型別進一步劃分-讀取或寫入,同步或非同步。 前兩個欄位指定裝置的主編號和次編號,第三個欄位指定操作型別,第四個欄位指定IO的數量。

-blkio.throttle.io_service_bytes
  -組從磁碟傳輸到磁碟或從磁碟傳輸的位元組數。 這些操作按操作型別進一步劃分-讀取或寫入,同步或非同步。 前兩個欄位指定裝置的主要和次要編號,第三個欄位指定操作型別,第四個欄位指定位元組數。

各種政策中的通用檔案
-----------------------------------
-blkio.reset_stats
  -將int寫入此檔案將導致重置該cgroup的所有統計資訊。

CFQ sysfs可調部分
=================
/sys/block/<disk>/queue/iosched/slice_idle
------------------------------------------
在速度更快的硬體上,CFQ可能會是慢的,尤其是在順序工作負載下。 發生這種情況是因為CFQ在單個佇列上處於空閒狀態,並且單個佇列可能不會驅動更深的請求佇列深度來保持儲存繁忙。 在這種情況下,可以嘗試設定 slice_idle = 0,然後在支援NCQ的硬體上將CFQ切換為IOPS(每秒IO操作)模式。

這意味著CFQ不會在cfq組的cfq佇列之間閒置,因此能夠驅動更高的佇列深度並獲得更好的吞吐量。 這也意味著cfq根據IOPS而不是磁碟時間來提供組之間的公平性。

/sys/block/<disk>/queue/iosched/group_idle
------------------------------------------
如果通過設定 slice_idle = 0禁用單個cfq佇列和cfq服務樹上的空閒,則會啟動group_idle。這意味著CFQ仍將在該組上保持空閒,以嘗試在組之間提供公平性。

預設情況下,group_idle 與 slice_idle 相同,並且如果啟用 slice_idle 則不執行任何操作。

如果您建立了多個組並將該應用程式放入該組中,而這些應用程式沒有驅動足夠的IO來保持磁碟繁忙,那麼總體吞吐量可能會下降。 在這種情況下,請設定 group_idle = 0,並且CFQ不會在單個組上空閒,並且吞吐量應該會提高。