虛擬機器IO資源爭搶的解決方法

weixin_34279579發表於2017-12-25

背景

由於Ceph儲存和Nova計算節點是混合部署的,而且虛擬機器的資料卷是共用Ceph的Volume儲存池。難免會出現叢集中某一臺虛擬機器的資料卷io飈高的情況,造成其他虛擬機器iowait跟著飈高。出現這種情況對於io比較敏感的業務是災難性的。大部分情況,業務虛擬機器會隨著磁碟io下降自動恢復。但是很多情況我們並不希望叢集內出現這種io資源搶佔的情況。

方案

第一種

對於io密集型的虛擬機器,我們通常採用高效能的儲存叢集來滿足此類業務的需求。

Ceph方面

利用SSD硬碟或者高效能硬碟建立一個新的儲存池,手動修改CRush,將新硬碟關聯到新儲存池

OpenStack方面

  1. 配置cinder.conf,建立一個新的volume-backend
  2. 建立新的volume-type,io高密集的卷建立在新的volume-type裡面

第二種

對於Ceph儲存本身是低成本的構建架構,沒有SSD或者高效能硬碟時,只能通過限制虛擬機器對於資料卷的讀寫io或者速率了。

Ceph方面

沒有對於配置,目前我用的Jewel版本暫時不支援RBD的Qos設定,後面新版本也許支援

OpenStack方面

1. Qos策略

Cinder的Qos支援前端和後端兩種策略,前端是在qemu中實現,後端是在儲存叢集上實現。由於Ceph不支援,那我們就只能在前端實現

目前前端qemu支援配置的qos key如下:

  • total_bytes_sec: the total allowed bandwidth for the guest per second
  • read_bytes_sec: sequential read limitation
  • write_bytes_sec: sequential write limitation
  • total_iops_sec: the total allowed IOPS for the guest per second
  • read_iops_sec: random read limitation
  • write_iops_sec: random write limitation

2. 實現方法

通過呼叫libvirt介面,對資料卷新增了iotune資訊,如下:

建立標準和關聯qos

# cinder qos-create middleRW.limit  consumer="front-end"  read_iops_sec=300 write_iops_sec=300 read_bytes_sec=104857600 write_bytes_sec=62914560
# cinder qos-associate  <qos_specs> <volume_type_id>

libvirt中對資料卷的限制

</disk>
    <disk type='network' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <auth username='cinder'>
        <secret type='ceph' uuid='48baec00-46f8-4aa1-908f-c7991961b022'/>
      </auth>
      <source protocol='rbd' name='volumes/volume-756ed2a4-5c54-4b02-956f-e1ec371a2c58'>
        <host name='10.33.64.100' port='6789'/>
        <host name='10.33.64.101' port='6789'/>
        <host name='10.33.64.102' port='6789'/>
        <host name='10.33.64.103' port='6789'/>
        <host name='10.33.64.104' port='6789'/>
      </source>
      <backingStore/>
      <target dev='sdb' bus='scsi'/>
      <iotune>
        <read_bytes_sec>104857600</read_bytes_sec>
        <write_bytes_sec>41943040</write_bytes_sec>
        <read_iops_sec>300</read_iops_sec>
        <write_iops_sec>300</write_iops_sec>
      </iotune>
      <serial>756ed2a4-5c54-4b02-956f-e1ec371a2c58</serial>
      <alias name='scsi0-0-0-1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>

3. 簡單測試

限制之前

# dd bs=1M count=4k if=/dev/zero of=test conv=fdatasync
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 35.2682 s, 122 MB/s

寫限制在40M/s,基本滿足需求

# dd bs=1M count=4k if=/dev/zero of=test conv=fdatasync
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 102.72 s, 41.8 MB/s

其它

當然也可以用libvirt的blkdeviotune命令對虛擬機器做io限制,這樣不光可以對資料卷做限制,也可以對虛擬機器的根盤做個性化配置。


# virsh blkdeviotune myinstances sda --read-bytes-sec 104857600 --write-bytes-sec 41943040  --read-iops-sec 300 --write-iops-sec 300  --read-bytes-sec-max 104857600 --write-bytes-sec-max 41943040  --group-name drive-scsi0-0-0-1 --read-bytes-sec-max-length 1 --write-bytes-sec-max-length 1 --read-iops-sec-max-length 1 --write-iops-sec-max-length 1

# virsh blkdeviotune 8 sdb

total_bytes_sec: 0
read_bytes_sec : 104857600
write_bytes_sec: 41943040
total_iops_sec : 0
read_iops_sec  : 300
write_iops_sec : 300
total_bytes_sec_max: 0
read_bytes_sec_max: 10485760
write_bytes_sec_max: 4194304
total_iops_sec_max: 0
read_iops_sec_max: 30
write_iops_sec_max: 30
size_iops_sec  : 0
group_name     : drive-scsi0-0-0-1
total_bytes_sec_max_length: 0
read_bytes_sec_max_length: 1
write_bytes_sec_max_length: 1
total_iops_sec_max_length: 0
read_iops_sec_max_length: 1
write_iops_sec_max_length: 1

相關文章