AWS
Ansible

EC2 インスタンス(Amazon Linux)を clocksource=tsc にして現在時刻取得のオーバーヘッドを減らす

現在時刻の取得

プログラムを実行する上で、現在時刻を取得する処理が実行されることは少なくありません。意識的に実行していなくても、ロギング、乱数のシード生成、UUID の生成といった様々な用途で現在時刻が用いられていることがあります。

現在時刻の取得のオーバーヘッドを意識することは少ないかもしれませんが、Netfix 社の事例で CPU 使用率が 30% も改善したという事例が紹介されているぐらいですし、アプリケーションによっては実際にオーバーヘッドになる事例もありましたので、チューニングしておく価値があると思います。

TSC clocksource と Xen clocksource

ざっくりとした説明としては、それぞれ以下のような性質を持つ時刻の取得源です:

  • TSC clocksource : ユーザーランドで特定の CPU レジスタから時刻を読み取る。Linux Kernel や Xen hypervisor の呼び出しを伴わないので速い
  • Xen clocksource (Amazon Linux デフォルト): Kernel 経由で Xen の hypervisor から時刻を取得する。Kernel や hypervisor への切替を伴うので遅い。

詳細については記事末尾の参考記事などを参照ください。

なお、過去には TSC の利用は時刻がズレるため危険でしたが、2015 年時点ですでに TSC の利用は問題ない とされており、今では公式にも推奨されています。PV インスタンスで cat /proc/cpuinfo | grep constant_tsc などとすることでも TSC サポートが見て取れますし、利用することには問題ないのではないのでしょうか。

clocksource=TSC に切り替える Ansible 例

clocksource は Linux の起動時のパラメタによって変更することができます。

OS 起動設定を変える方法を(筆者が)よく忘れがちなので、初代 Amazon Linux と Amazon Linux 2 での Ansible の例を下記に記しておきます:

Amazon Linux

初代 Amazon Linux は grub 1 なので、grub.conf の kernel 行に直接 clocksource=tsc オプションを足します:

  - name: Change kernel parameter
    replace:
      dest: /boot/grub/grub.conf
      regexp: '^(kernel (?!.*clocksource=).*)$'
      replace: '\1 clocksource=tsc'

Amazon Linux 2

Amazon Linux 2 は grub 2 なので grub.conf は grub2-mkconfig で生成するのが正しいです。追加の設定は /etc/default/grub (中身はシェルスクリプト) に記述します:

  - name: Change kernel parameter
    lineinfile:
      dest: /etc/default/grub
      state: present
      regexp: "^GRUB_CMDLINE_LINUX="
      line: "GRUB_CMDLINE_LINUX=\"clocksource=tsc\""
      # 他にもオプションを渡したい場合は上記に追加するか、 GRUB_CMDLINE_LINUX=$GRUB_CMDLINE_LINUX clocksource=tsc などとする
    register: grub_cmdline_linux

  - name: update grub config
    command: /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg
    when: grub_cmdline_linux|changed

OS 稼働中に変更

一時的に動作を確認したい場合、OS 動作中に設定することもできます:

echo tsc > /sys/devices/system/clocksource/*/current_clocksource

clocksource の確認

以下のようにすることで確認できます:

$ cat /sys/devices/system/clocksource/*/current_clocksource
tsc

なお、利用可能な clocksource の一覧も確認できます:

$ cat /sys/devices/system/clocksource/*/available_clocksource
xen tsc hpet acpi_pm 

参考記事: