Идентификаторы UID и TSUID
В OpenTSDB, когда вы записываете временной ряд данных, он всегда ассоциируется с метрикой и по меньшей мере одной парой имя/значение тега. Каждой метрике, имени тега и значению тега присваивается уникальный идентификатор (UID) при первом их появлении или при явном назначении через API или утилиту командной строки. Комбинация метрики и пар имя/значение тегов создаёт идентификатор временного ряда или TSUID.
UID
Типы объектов UID включают:
-
метрика - метрика, такая как
sys.cpu.0илиtrades.per.second -
tagk - имя тега, например
hostилиsymbol. Это всегда «ключ» (первое значение) в паре ключ/значение тега. -
tagv - значение тега, такое как
web01илиgoog. Это всегда «значение» (второе значение) в паре ключ/значение тега.
Назначение
UID — это целое положительное число, уникальное для имени объекта UID и его типа. В системе хранения есть счётчик, который увеличивается для каждой metric, tagk и tagv. При создании новой таблицы tsdb-uid, этот счётчик устанавливается в 0 для каждого типа. Таким образом, если вы вставите новый элемент данных с метрикой sys.cpu.0 и парой тегов host=web01, у вас будет 3 новых объекта UID, каждый с UID 1.
UID автоматически назначаются новым объектам tagk и tagv при записи точек данных в TSD. Объекты metric также получают новые UID, но только если параметр автоматической метрики настроен на true. В противном случае точки данных с новыми метриками отклоняются. UID ищутся в кэшированном отображении для каждой входящей точки данных. Если поиск не удаётся, TSD попытается назначить новый UID.
Хранение
По умолчанию UID кодируются в 3 байта в хранилище, что даёт максимальный уникальный идентификатор 16 777 215 для каждого типа UID. Это делается для уменьшения занимаемого места в хранилище и снижения объёма памяти TSD. Для подавляющего большинства пользователей 16 миллионов уникальных метрик, 16 миллионов уникальных имён тегов и 16 миллионов уникальных значений тегов должно быть достаточно. Но если вам нужно больше определённого типа, вы можете изменить исходный код OpenTSDB и перекомпилировать его с 4 байтами или более. С версии 2.2 вы можете переопределить размер UID через файл конфигурации.
Предупреждение
Если вы измените число кодирования байтов, вы должны начать с новой таблицы tsdb и новой таблицы tsdb-uid, в противном случае результаты будут непредсказуемыми. Если у вас есть данные в существующей настройке, вы должны экспортировать их, удалить все таблицы, создать их заново и повторно импортировать данные.
Отображение
UID можно отображать несколькими способами. Наиболее распространённый метод — через HTTP-API, где 3 байта данных UID кодируются как шестнадцатеричная строка. Например, UID 1 был бы записан в двоичном виде как 000000000000000000000001. В виде массива беззнаковых байтовых значений, его можно представить как [0, 0, 1]. В кодировке шестнадцатеричной строки значение будет 000001, где строка дополнена нулями для каждого байта. UID 255 будет иметь шестнадцатеричное значение 0000FF (или в виде массива байтов [0, 0, 255]). Для преобразования из десятичного UID в шестнадцатеричный используйте любой инструмент преобразования в шестнадцатеричный формат и добавляйте нули перед полученным значением, пока не получите 6 символов. Для преобразования из шестнадцатеричного UID в десятичный просто удалите все нули спереди, затем используйте инструмент для преобразования шестнадцатеричной строки в десятичную.
В некоторых утилитах командной строки и файлах журналов UID может отображаться как массив знаковых байтов (благодаря Java), например, в вышеприведённом примере [0, 0, 1] или [0, 0, -28]. Для преобразования из этого знакового массива в массив беззнаковых байтов, а затем в шестнадцатеричное представление. Например, -28 будет двоичным 10011100, что даст десятичное значение 156 и шестнадцатеричное значение 9C.
Изменение
UID можно переименовать или удалить. Переименование можно выполнить через командную строку, и это обычно безопасно, но повлияет на ВСЕ временные ряды, которые включают переименованный идентификатор. Например, если у нас есть ряд sys.cpu.user host=web01 и другой apache.requests host=web01 и мы переименуем значение тега web01 в web01.mysite.org, то оба ряда теперь будут отражать новое имя хоста, и все запросы, относящиеся к старому имени, необходимо обновить. Если приходит точка данных с предыдущей строкой, будет назначен новый UID.
Удаление UID может быть сложным с версии 2.2. Удаление метрики безопасно, так как пользователи больше не смогут запрашивать данные, и они не появятся в вызовах API для предложений. Однако удаление имени или значения тега может привести к сбоям в запросах. Например, если у вас есть временные ряды для метрики sys.cpu.user с хостами web01, web02, web03 и т. д., и вы удаляете UID для web02, любой запрос, который будет сканировать данные, включающие ряд sys.cpu.user host=web02, выдаст исключение пользователю, потому что данные остаются в хранилище. Мы настоятельно рекомендуем выполнить FSCK с запросом для исправления таких проблем.
Зачем нужны UID?
Этот вопрос задаётся достаточно часто, поэтому стоит объяснить причины. Поиск или назначение UID занимает ценные ресурсы TSD, поэтому люди задаются вопросом, не было бы быстрее использовать исходное имя метрики или вычислить хеш. Действительно, с точки зрения записи это было бы немного быстрее, но есть ряд недостатков, которые становятся очевидными.
Необработанные имена
Поскольку OpenTSDB использует HBase в качестве уровня хранения, вы можете использовать строки в качестве ключа строки. Следуя текущей схеме, у вас может быть ключ строки, который выглядел как sys.cpu.0.user 1292148000 host=websv01.lga.mysite.com owner=operations. Порядок будет аналогичен существующей схеме, но теперь вы используете 70 байт хранилища каждый час вместо 19. Кроме того, ключ строки должен быть записан и возвращён с каждым запросом к HBase, поэтому вы также увеличиваете использование сети. Поэтому использование UID может помочь сэкономить место.
Хеши
Другая идея — просто увеличить UID до 4 байтов, затем вычислить хеш для строк и сохранить хеш с прямым и обратным отображениями, как мы это делаем сейчас. Это определённо сократило бы время назначения UID, но есть несколько проблем. Во-первых, вы столкнётесь с коллизиями, когда разные имена возвращают один и тот же хеш. Вы можете попробовать разные алгоритмы и даже увеличить хеш до 8 байтов, но у вас всегда будет проблема с коллизиями хешей. Во-вторых, вы теперь добавляете вычисление хеша к каждой записи данных, поскольку ему нужно будет определить хеш, а затем найти хеш в таблице UID, чтобы увидеть, сопоставлен ли он уже. Сейчас каждая точка данных выполняет только поиск. В-третьих, вы не можете так просто предварительно разделить свои регионы HBase. Если вы знаете, что в вашей системе будет примерно 800 метрик (теги для этой цели не имеют значения), вы можете предварительно разделить свою таблицу HBase, чтобы равномерно распределить эти 800 метрик и повысить исходную производительность записи.
TSUID
При записи точки данных в OpenTSDB, ключ строки форматируется как <metric_UID><timestamp><tagk1_UID><tagv1_UID>[...<tagkN_UID><tagvN_UID>]. Просто удалив метку времени из ключа строки, мы получаем длинный массив UID, который в совокупности образует уникальный идентификатор временного ряда. Кодирование байтов как шестнадцатеричной строки даст нам полезный TSUID, который можно передавать различным вызовам API. Таким образом, по нашему примеру UID выше, где метрика, имя тега и значение имеют UID 1, наш TSUID, закодированный как шестнадцатеричная строка, будет 000001000001000001.
Хотя этот формат TSUID может быть длинным и некрасивым, особенно с множеством нулей для ранних UID, есть несколько причин, почему это полезно:
- Если вы знаете ширину каждого UID (по умолчанию 3 байта, как указано выше), то вы можете легко разобрать UID для каждой метрики, имени тега и значения из строки UID.
- Назначение уникального числового идентификатора для каждого временного ряда создаёт проблемы с блокировкой и/или проблемами синхронизации, где временной ряд может быть пропущен, если UID не удастся инкрементировать.
© 2010–2016 The OpenTSDB Authors
Licensed under the GNU LGPLv2.1+ and GPLv3+ licenses.
http://opentsdb.net/docs/build/html/user_guide/uids.html