Производительность серверов БД в OE 12
Улучшение производительности BHT
Хэш-таблица буферного пула (BHT) – это хэш-таблица, которая содержит указатели на блоки базы данных, которые были скопированы в буферы, хранящиеся в буферном пуле базы данных (-B). Каждый просмотр буферного пула, включая для доступа к индексам и данным, использует BHT для определения местоположения этих данных в разделяемой памяти. BHT обеспечивает быстрый поиск данных в буферном пуле всякий раз, когда пользовательское приложение запрашивает данные.
Как и большинство механизмов хеширования, BHT принимает в качестве входных данных хэш-ключ (уникальный ключ блока базы данных) и применяет к нему функцию хеширования, чтобы найти запись в таблице BHT. Как и большинство хэш-таблиц, которые не связывают хэш-ключ с данным один к одному, каждая запись BHT фактически является «корзиной» элементов, организованных в виде связанного списка указателей буферного пула (см. Рис.1). Таким образом, уникальный ключ блока базы данных или ROWID сопоставляется с соответствующим буфером в буферном пуле (-B).
По умолчанию размер BHT приблизительно равен 25% от размера буферного пула (-B), который можно изменить, указав другое значение для параметра старта базы данных -hash. По мере того, как страницы блоков входят и выходят из буферного пула, должны обновляться соответствующие BHT-записи. А так как BHT является модифицируемой структурой, доступ к ней должен быть защищён во время изменения. Доступ защищён серией BHT-латчей, которые обеспечивают эксклюзивный доступ к BHT-секциям. Статистика активности BHT-латча, сообщаемая системой, представляет собой суммирование информации о нескольких используемых латчей BHT.
Для повышения эффективности доступа к BHT применялись два отличающихся метода. В первом, нужно было улучшить параллелизм BHT путём уменьшения объёма информации, заблокированной эксклюзивным доступом для отдельных поисков. Во втором, необходимо полностью избежать ненужного использования BHT за счёт оптимистичного подхода к доступу к индексным данным в буферном пуле базы данных.
Как отмечалось ранее, доступ к данным должен быть защищён поскольку информация, хранящаяся в структуре данных BHT, является общей для всех подключений и изменяется по мере того, как страницы данных входят и выходят из буферного пула. Данные защищены с помощью механизма латчей, который обеспечивает исключительный доступ к структуре данных так, чтобы структура не изменялась для отдельного поиска.
Такая высоко-доступная структура данных может стать предметом разногласий, когда многие соединения баз данных запрашивают данные одновременно. Поэтому чтобы увеличить параллелизм одновременного поиска, BHT должен быть защищён несколькими латчами, а не одним. А поскольку BHT разбит на защищённые отдельными латчами секции, то параллелизм улучшается за счёт уменьшения объёма данных, защищённых исключительным доступом одним BHT-латчем.
Проблема состоит в том, чтобы определить, сколько латчей должно быть предусмотрено для защиты BHT. Это баланс объёма выделяемой памяти по сравнению с производительностью. Установка «один к одному», как правило, работает лучше всего, но использует больше памяти. Кроме того, это усложняет механизм, когда необходимо удерживать более одного латча BHT одновременно.
За несколько выпусков OpenEdge количество латчей, защищающих BHT, увеличилось с 1 до 4, затем до 256 и до 1024. Однако размер буферного пула базы данных (-B), устанавливаемого клиентами, также увеличился. Нередко можно увидеть -B, установленную миллионами. Например, при -B, равном 6 000 000, примерно 6000 указателей буферного пула BHT будут заблокированы исключительно каждым запросом данных. Кроме того, клиенты работают с большим числом подключений к базе данных (-n), что увеличивает конкуренцию за одновременный доступ к общим данным.
Предыдущие попытки улучшить производительность BHT с помощью латчей чтения/записи не показали многообещающих результатов в этой среде, вероятно, из-за накладных расходов на их реализацию. А поскольку процессоры становятся быстрее, это может потребовать дополнительных исследований.
Вместо того чтобы просто увеличить количество латчей до некоторого большего значения, был введён коэффициент хеширования латчей, который устанавливает количество латчей BHT в процентах от BHT (-hash). Поскольку-хэш изменяется по мере увеличения -B, то увеличивается и количество латчей, защищающих адреса записей буфера, указанных в BHT. Поэтому ожидается, что это усовершенствование будет продолжать улучшать параллелизм случайных обращений BHT независимо от растущего размера -B.
В дополнении к улучшению одновременного доступа к случайным данным через BHT, ещё один способ повысить производительность в этой области заключается в том, чтобы полностью избежать ненужного эксклюзивного доступа к общему ресурсу. При обращении к данным доступ к ним осуществляется через ROWID, который обычно получается из индексного поиска. Для поиска отдельных записей одним из направлений улучшения производительности доступа BHT была реализация технологии коэффициент хеширования латчей, о которой было рассказано выше.
Дальнейшее улучшение поиска при сканировании нескольких записей, например в операторе «for each» или «query», может быть достигнуто с помощью техники «базы данных в памяти» (in-memory database), позволяющей сократить количество обращений к BHT для получения необходимых ROWID из соответствующего индекса. Этот метод делает существующий пессимистический алгоритм оптимистичным алгоритмом, предполагая, что расположение в памяти последнего индексного блока, к которому обращались, не изменится до следующего поиска.
Индексы, поддерживаемые в базе данных OpenEdge, используют технику, которая сильно сжимает данные в отдельном индексном блоке. Поэтому индексный блок может содержать тысячи индексных записей, используемых для извлечения идентификаторов строк, которые удовлетворяют конкретному запросу. Оба механизма SQL и ABL запрашивают идентификаторы строк из индекса последовательно, чтобы удовлетворить запрос по одному за раз. Несмотря на то, что индексный курсор всегда запоминает номер блока базы данных, к которому последний раз обращались, при каждом обращении к индексному блоку, он использует BHT, чтобы найти, где находится индексный блок в памяти. Этот алгоритм защищает от ссылки на запомненный индексный блок, который больше не находится в пуле буферов базы данных.
Это пессимистичный подход к доступу к данным. Благодаря тому, как происходит управление буферами базы данных в буферном пуле, крайне редко случается так, что индексный блок, к которому только что обращались, будет выгружен из буферного пула до следующего поиска. Изменение алгоритма на оптимистичный, то есть предполагающий, что последний индексный блок, к которому обращались, всё ещё будет существовать в буферном пуле и точно в том же месте при следующем обращении, означает, что нет необходимости обращаться к BHT для его поиска.
Устранение необходимости в эксклюзивном доступе к любой структуре данных – это лучший способ улучшить параллелизм. Конечно, чтобы гарантировать, что доступ по запомненному адресу обеспечит доступ к желаемому буферу, должна быть выполнено соответствующая проверка, но такая проверка уже выполнена для существующего пессимистичного алгоритма, поэтому для использования оптимистичного подхода не требуется никаких дополнительных затрат.
В редких случаях, когда буфер может оказаться не тем, который требуется, его поиск будет выполнен как в прошлом с использованием BHT. В зависимости от удовлетворяющих определённому запросу количества индексных записей, этот оптимистичный подход может в тысячи раз сократить количество поисков с использованием BHT на каждый сканируемый индексный блок.
Метка:Производительность