Ceph Object Gateway (RadosGW): performance monitoring

RadosGW или RGW он же Ceph Object Gateway позволяет работать с хранилищем RADOS(он же Ceph) через REST API совместимый с S3 и Swift. RGW является прослойкой между пользователем использующим REST и хранилищем RADOS взаимодействие с которым осуществляется по алгоритму CRUSH.
У всех компонентов Ceph есть метрики позволяющие мониторить производительность и понимать, что происходит в кластере. У RGW тоже есть такие метрики и они нам сильно помогают понимать состояние системы в целом и находить проседающие места.

Получение метрик

ceph --admin-daemon /var/run/ceph/ceph-client.radosgw.ss10.asok perf dump

Метрики запрашиваются через сокет конкретного экземпляра RGW. И это метрики именно этого экземпляра.
Путь к сокету формируется обычно примерно так:  /var/run/ceph/ceph- + rgw_name + .asok где rgw_name это уникальное имя экземпляра RGW из ceph.conf:

[client.radosgw.ss10]
    pid file = /var/run/ceph/client.radosgw.ss10.pid
    host = ss10
    keyring = /etc/ceph/ceph.client.ss10.keyring
…

Наиболее интересные метрики:

"client.radosgw.ss10": {
    "req": 70715,
    "failed_req": 41737,
    "get": 9,
    "get_b": 1048572,
    "get_initial_lat": {
        "avgcount": 4,
        "sum": 0.019146922
    },
"put": 168,
    "put_b": 44040192,
    "put_initial_lat": {
        "avgcount": 168,
        "sum": 8.006931290
    },
"qlen": 0,
    "qactive": 0,
    "cache_hit": 20832,
    "cache_miss": 36936,
    "keystone_token_cache_hit": 0,
    "keystone_token_cache_miss": 0
},
...

Значения метрик

req — все хапросы, что пришли, совершенно любые, в том числе, например сurl без параметров,

failed_req — в исходном коде RGW подписана как “Aborted requests”, что довольно не однозначно. По моим наблюдениям сюда попадают запросы завершившиеся не с “положительным” http-кодом, например с 404 (Not Found, NoSuchBucket и т.д.),

get — количество запросов типа HEAD/GET,

get_b — суммарный объем данных в get-запросах. Сколько данных скачано через этот RGW с момента начала его работы,

get_initial_lat — сложная метрика. Точнее ее сложно обсчитывать для мониторинга. Тут есть avgcount, что является числом именно get-запросов и sum, что является суммарным временем выполнения этих запросов. Что бы получить примерное время обработки одного запроса нужно делить sum на avgcount. При этом, это нужно брать не текущие значения за все время которые всегда растут а с дельту которая появляется между забором метрик. То есть на каждой новой проверке нужно где то брать предыдущие значения этих метрик, что бы получить дельту за время с последней проверки и уже значения дельт делить(sum_delta / avgcount_delta). Тогда получится среднее время запроса за период проверки,

put — все put-запросы?

put_b — Сколько данных загружено через этот RGW

put_initial_lat — тоже самое как и get_initial_lat, высчитывать так же,

qactive — один из самых интересных параметров. В исходном коде отмечен как “Active requests queue”. Число потоков которые использованы в настоящий момент. По умолчанию у каждого инстанса RGW может быть максимум 100 потоков. Соответственно когда все потоки будут задействованы, RGW не сможет принимать новые запросы. Если вы наблюдаете периодическую утилизацию всех потоков RGW то возможно есть две проблемы. Кластер Ceph не справляется с нагрузкой и очень долго выполняет запросы RGW. Если у вас нет мониторинга Ceph, что бы это понять, то можно посмотреть на метрики get_initial_lat,put_initial_lat и в таких случаях должна расти latency. Второй случай когда с самим Ceph все хорошо и запросов просто слишком много. В такой ситуации нужно добавлять инстансы RGW или увеличивать число потоков.

qlen — В исходном коде подписан как «Queue length”.  В теории все понятно, но на практике, мне лично нет. Когда все потоки(qactive) RGW утилизированы, то начинает расти счетчик qlen, что логично, но я не понимаю, почему он растет только до 12. В общем не нужно допускать роста значения этого счетчика)

cache_hit — попадания в cache метаданных. RGW кеширует метаданеые объектов запросы к которым он обработал и тем самым ускоряет отработку последующих операций с этими объектами. По умолчанию размер кеша равен 10000 записей. Я пока не могу сказать увеличивать его значение или нет и в каких случаях. По логике, если ваш кластер Ceph не справляется с текущей нагрузкой, увеличение размера кеша приведет к еще большей нагрузке. С другой стороны RGW будет меньше читать индекс бакетов, что по идее снизит немного нагрузку. Тут нужны эксперименты, которые я еще не проводил.

cache_miss — промахи в cache метаданных.

Еще интересный момент. Например метод S3 API copy-object не увеличивает счетчики get, put только счетчики req. Данные через RGW фактически не проходят но при этом в самом кластере ceph данные копируются, что может создавать серьезную нагрузку при этом в мониторинге RGW может например начать рости lanency хотя нет никаких тяжелых get/put запросов.

Сброс счетчиков

Счетчики сбрасываются при рестарте rgw или это можно сделать вручную:

ceph --admin-daemon /var/run/ceph/ceph-client.radosgw.ss10.asok perf reset all

Можно сбросить счетчики отдельных метрик, см help:

ceph --admin-daemon /var/run/ceph/ceph-client.radosgw.ss10.asok help
{
    "config diff": "dump diff of current config and default config",
    "config get": "config get <field>: get the config value",
    "config set": "config set <field> <val> [<val> ...]: set a config variable",
    "config show": "dump current config settings",
    "get_command_descriptions": "list available commands",
    "git_version": "get git sha1",
    "help": "list available commands",
    "log dump": "dump recent log entries to log file",
    "log flush": "flush log entries to log file",
    "log reopen": "reopen log file",
    "objecter_requests": "show in-progress osd requests",
    "perf dump": "dump perfcounters value",
    "perf reset": "perf reset <name>: perf reset all or one perfcounter name",
    "perf schema": "dump perfcounters schema",
    "version": "get ceph version"
}

Собственно, все. Мониторить описанные метрики вы можете любым удобным для вас способом. Мы используем Zabbix и в следующей статье, покажу как мы это делаем у себя.