Персистентность

ADS в значительной степени опирается на файловую систему для хранения и кэширования сообщений. Существует общее представление о том, что “диски медленные”, и это заставляет скептически относиться к тому, что персистентная структура может предложить конкурентоспособную производительность. На самом деле диски могут быть и намного медленнее, и намного быстрее в зависимости от того, как они используются. И правильно разработанная структура диска часто может быть такой же быстрой, как и сеть.

Ключевым фактом о производительности диска является то, что пропускная способность жестких дисков отличается от латентности диска в течение последнего десятилетия. В результате производительность линейных записей в конфигурации JBOD с шестью массивами SATA RAID-5 размером 7200 об/мин составляет около 600 МБ/с, но производительность операции случайной записи составляет всего около 100 к/сек – разница более 6000X. Эти линейные операции чтения и записи являются наиболее предсказуемыми для всех моделей использования и сильно оптимизированы операционной системой. Современная ОС предоставляет технологии опережающего чтения и записи, которые обеспечивают предварительную выборку данных в больших кратных блоках и группируют меньшие логические записи в большие физические записи. Дальнейшее обсуждение этой проблемы можно найти в статье ACM Queue, где показывается, что последовательный доступ к диску может в некоторых случаях быть быстрее, чем случайный доступ к памяти.

Для компенсации расхождения в производительности современные операционные системы становятся все более агрессивными в использовании основной памяти для кэширования диска. Современная ОС может перенаправить всю свободную память на кэширование диска с небольшим снижением производительности при восстановлении памяти. Все операции чтения и записи на диск будут проходить через этот единый кэш. Но данная функция не может быть легко отключена без использования прямого ввода-вывода, поэтому, даже если процесс поддерживает встроенный кэш данных, эти данные, вероятно, будут дублироваться в pagecache операционной системы, сохраняя все дважды.

Платформа ADS строится поверх JVM, и всем, кто сталкивался с использованием памяти Java, известно:

  • Накладные расходы памяти на объектах очень высоки, что часто удваивает размер хранимых данных;
  • Сбор мусора Java становится все более неудобным и медленным по мере увеличения объема данных in-heap.

В результате этих факторов, используя файловую систему и полагаясь на pagecache, лучше поддерживать кэш in-memory или другую структуру – при наличии свободной памяти появляется возможность использовать ее в качестве второго кэша. Это приводит к кэшу до 28-30 ГБ на машине 32 Гб без ограничений сборщиков мусора. Кроме того, кэш остается теплым, даже при перезагрузке сервиса. В то время как кэш in-process необходимо перестраивать в памяти (что для кэша 10 ГБ может занять до 10 минут), иначе ему придется стартовать с полностью холодного кэша (что приводит к снижению производительности). К тому же значительно упрощается код, поскольку вся логика поддержания согласованности между кэшем и файловой системой теперь находится в ОС, которая имеет тенденцию делать это более эффективно и правильно, чем однократные попытки in-process. Если использование диска способствует линейному чтению, то опережающее чтение эффективно заполняет этот кэш полезными данными на каждом диске.

В ADS предлагается другая простая структура: вместо того, чтобы содержать все данные in-memory, и когда заканчивается пространство полностью очищать файловую систему, инвертировать данный процесс и записывать все данные сразу же в постоянный журнал файловой системы без необходимости сброса на диск. По сути это просто означает, что данные переносятся в pagecache ядра.

Такой ориентированный на pagecache стиль описывается в статье Notes from the Architect.

Персистентная структура данных, используемая в системах обмена сообщениями, часто представляет собой очередь для каждого потребителя со связанным BTree или другими структурами данных произвольного доступа общего назначения для поддержки метаданных о сообщениях. BTrees являются наиболее универсальной структурой данных и позволяют поддерживать широкий спектр транзакционной и нетранзакционной семантики в системе обмена сообщениями. Они имеют довольно высокую стоимость, однако: Btree операции – O (log N). Обычно O (log N) считается эквивалентным постоянному времени, но это не относится к дисковым операциям. Диск выполняет поиск за 10 мс, и каждый диск может делать только один поиск за раз, поэтому параллелизм ограничен. Следовательно, даже небольшое количество запросов на диск приводит к очень высоким накладным расходам. Поскольку системы хранения данных сочетают очень быстрые кэшированные операции с очень медленными физическими дисковыми операциями, наблюдаемая производительность древовидных структур часто суперлинейна по мере увеличения данных с фиксированным кэшем, то есть дублирование данных – это намного хуже по сравнению с вдвое медленной скоростью.

Интуитивно персистентная очередь может быть построена на простых операциях чтения и добавления к файлам, как это бывает с решениями по ведению журнала. Такая структура имеет преимущество в том, что все операции – O (1), и операции чтения не блокируют операции записи или друг друга. Это имеет очевидные преимущества в производительности, так как она полностью отделена от размера данных. Один сервер теперь может в полной мере использовать ряд дешевых и низкоскоростных дисков 1+TB SATA. Хотя у них низкая производительность поиска, она приемлема для многочисленных операций чтения и записи и достигает 1/3 цены и 3x емкости.

Имея доступ к практически неограниченному дисковому пространству без какого-либо снижения производительности ADS может предоставить некоторые функции, которые обычно не встречаются в системах обмена сообщениями. Например, в ADS вместо того, чтобы удалять сообщения сразу после их считывания, можно сохранять их в течение относительно длительного периода, что приводит к большой гибкости для потребителей.