Giter Site home page Giter Site logo

lsd's Introduction

Что такое LSD?

LSD — это демон, который разработан для замены scribe от Facebook, который сам Facebook забросил и больше не поддерживает. Демон осуществляет доставку событий произвольного формата на заданные сервера. Требований к формату сообщения два: сообщение должно оканчиваться переводом строки и не должно быть больше 1 Мб.

Минимальные требования к замене scribe, которыми мы руководствовались:

  • Надежная доставка событий — каждое отправленное событие должно быть доставлено приемникам как минимум 1 раз
  • В случае недоступности приемника, события должны буферизоваться на диск
  • Работа в качестве роутера — все события идут на набор роутеров, откуда уже доставляются конечным потребителям
  • Доставка указанных пользователем категорий на различные группы серверов (например, debug_* идет на logs1.mlan, остальное — на scribeuds1.mlan и scribeuds2.mlan по алгоритму round-robin)
  • Доставка событий на конечные сервера в файлы вида "<target_dir>/<category>/<filename>" и поддержание симлинка вида "<category>_current" на файл, в который в данный момент идет запись
  • Open-source
  • Разделение потока событий с помощью алгоритма round-robin или по хешу от заданного идентификатора (например, шардинг по user_id)
  • Устойчивость к падению клиента, сервера, роутеров и приемников — конкретнее, события должны продолжать доставляться, даже если один из роутеров или один из консьюмеров недоступны

Сборка

  1. Убедиться, что у вас macOS или Linux
  2. Установить go с сайта https://golang.org/
  3. Установить LSD: go get github.com/badoo/lsd

Конфигурация

Конфигурация по умолчанию берется из "conf/lsd.conf". Чтобы указать свой путь до конфига, нужно использовать ключ "-c <config_path>". Поскольку lsd является демоном на нашем «сишном» фреймворке, его секция конфигурации для демона ничем не отличается от остальных демонов. Пример:

"daemon_config": {
    "listen": [
        { "proto": "lsd-gpb",                  "address": "0.0.0.0:3701" },
        { "proto": "lsd-gpb/json",             "address": "0.0.0.0:3702" },
        { "proto": "service-stats-gpb",        "address": "0.0.0.0:3703" },
        { "proto": "service-stats-gpb/json",   "address": "0.0.0.0:3704" },
    ],
    "max_cpus": 0,
    "http_pprof_addr": "0.0.0.0:3705",
    "pid_file": "/tmp/lsd.pid",
    "log_file": "-",
    "log_level": "NOTICE", /* для продакшен-использования не рекомендуется использовать уровень DEBUG */
    "service_name": "lsd",
    "service_instance_name": "<hostname>",
},

Остальные секции будут описаны ниже. В конфигурации должна быть задача либо секция для сервера, либо для клиента, либо обе (роутинг, см. дополнительные настройки для клиента в этом случае):

Server config:

«Сервером» в LSD называется сторона-приемник, которая пишет принятые события в отдельную директорию. Термин взят по аналогии со scribe. У сервера есть только одна обязательная опция, которая конфигурируется — директория, в которую должны приниматься все события:

"server_config": {
    "target_dir": "/local/tmp/lsd-target/",
},

События будут разбиты по категориям, на каждую категорию будет создано по одной директории в соответствии с её названием. Опциональные настройки:

  • max_file_size (в байтах) — регулирует максимальный размер получающихся файлов. Соблюдается нестрого, возможно создание файлов большего размера, погрешность может составлять около 1000 строк.
  • file_rotate_interval (в секундах) — максимальное количество секунд, которое должно пройти перед созданием нового файла. Соблюдается также нестрого — новый файл создается только при приходе первого события по прошествии указанного интервала. События должны приходить намного чаще, чем file_rotate_interval, чтобы эта опция работала с минимальной погрешностью.

Также можно задать ключ per_category_settings, в котором нужно положить массив объектов, которые содержат те же поля, но ещё с указанием ключа categories, который является списком масок категорий, для которых нужно применить кастомные настройки:

"per_category_settings": [
    {
        "categories": ["ololo_*", "trololo_*"],
        "max_file_size": 1000000,
        "file_rotate_interval": 5,
    }
],

Client config:

«Клиентом» в LSD называется сторона-отправитель, которая доставляет события на заданные сервера. Лучше всего формат клиентской части конфига описывает соответствующая секция в proto-файле:

message client_config_t {
    message receiver_t {
        required string addr = 1;
        required uint64 weight = 2;
    };
 
    message routing_config_t {
        repeated string categories = 1; // category masks list (only "*" is supported as mask)
        repeated receiver_t receivers = 2;
        optional bool prefix_sharding = 3 [default = false];
    }
 
    required string source_dir = 1;
    repeated routing_config_t routing = 2;
    optional uint64 max_file_size = 3 [default = 1000000]; // max file size for plain files before rotation
    required string offsets_db = 4;
    optional uint64 usage_check_interval = 5 [default = 60]; // file usage check interval in seconds
    optional bool always_flock = 6 [default = false]; // always flock files, required for re-streaming
};

Поле source_dir:

Директория, из которой берутся события для последующей отправки.

Имя файла должно быть в одном из следующих форматов:

  1. category, category.log, category/anything — запись в такие файлы должна осуществляться атомарно, то есть O_APPEND + блоки размером не более PIPE_BUF (4 Кб в линуксе)
  2. category_big, category_big.log, category/anything_big, category/anything_big.log — если у файла есть суффикс "_big", то на время чтения из файла берется LOCK_SH, соответственно запись в такие файлы должны идти тоже с O_APPEND + flock(LOCK_EX)

Имя категории получается либо из имени директории, либо из имени файла, если файл находится прямо в source_dir вместо нахождения в собственной поддиректории.

Удалением и ротацией доставленных файлов занимается сам LSD, никаких дополнительных скриптов не требуется. Перед ротацией LSD добавляет к имени файла суффикс ".old", поэтому не нужно самим писать в файлы с таким суффиксом. Если файл все ещё открыт на запись хотя бы одним из процессов, то файл не будет удален и события не потеряются.

Остальные поля:

  • max_file_size (в байтах) — максимальный размер файла перед его ротацией (используется в случае, если запись происходит в файл вида "category.log" или "category_big.log"
  • offsets_db — путь до файла со смещениями прочитанных файлов (например, /tmp/lsd-offsets.db). Важно, чтобы этот файл находится не на том же разделе, куда происходит запись файлов с событиями, иначе демон запаникует, когда на соответствующем разделе закончится место — в этом случае паника обязательна, потому что иначе демон не сможет отслеживать, какие файлы прочитаны до каких смещений
  • usage_check_interval (в секундах) — интервал проверки использования файлов. Используется при удалении ".old"-файлов. Сканирование происходит путем анализа procfs, поэтому довольно затратно по CPU. Рекомендуется оставить интервал по умолчанию
  • always_flock — нужно ли всегда делать flock(...) при чтении из файлов — необходимо выставить в true в случае ре-стриминга («роутеры» в терминах scribe)

Конфиг маршрутизации (поле «routing»)

В этом поле задается список машрутов — обязательно один маршрут по умолчанию (в котором не указан список категорий), и опционально задаются маршруты для указанных масок категорий. Пример конфигурации, в которой сообщения по умолчанию доставляются на scribeuds1 и scribeuds2, а события с префиксом debug_* — на logs1:

"routing": [
    {
        "receivers": [
            {"addr": "scribeuds1:3701", "weight": 1},
            {"addr": "scribeuds2:3701", "weight": 1},
        ],
    },
    {
        "categories": ["debug_*"],
        "receivers": [
            {"addr": "logs1:3701", "weight": 1},
        ],
    },
]

lsd's People

Contributors

yuriynasretdinov avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.