Массивные ветки данных Схема подписки (1) Алгоритм Программа

Java

В данной работе описан алгоритм подбиблиотеки подтаблиц программы, по каким правилам делятся. Некоторые правила в настоящее время появляются относительно постепенно, и, наконец, рекомендуется пятое решение для инкрементной миграции, и я представляю себе этот путь. Проблемы, вызванные последующей главой, описывают выбор технологии и подтаблицу подбиблиотеки.

задний план

По мере увеличения объема бизнеса и увеличения объема данных в таблице будет храниться большой объем данных.Когда таблица содержит 10 миллионов строк данных, оптимизация и повышение производительности машины с помощью SQL по-прежнему доступны. Для долгосрочной перспективы в будущем база данных и таблица должны быть в определенной степени разделены, например, когда возникает узкое место в производительности базы данных, и добавление полей занимает много времени. Решите проблему, связанную с тем, что независимые узлы должны нести все данные, распределять несколько узлов, обеспечивать отказоустойчивость и избавляться от необходимости зависания всей системы, чтобы сделать ее недоступной.

Цель

Схема подтаблицы подбазы данных, описанная в этой статье, основана на горизонтальном разделении, выборе различных правил и сравнении преимуществ и недостатков правил. Как правило, в Интернете перечислены первые три, а обычный скажет, что четвертый, но он не идеален. Первые несколько видов данных миграции будут иметь большое влияние. Я рекомендую пятый план, который я считаю лучше.

  • Вариант 1: Берём по модулю Ключа, а делитель постепенно увеличиваем
  • Вариант 2: разделить по времени
  • Вариант 3: По диапазону значений
  • Вариант 4: Концепция согласованного хэша — план равного распределения (публичный Dianping использует это, 200G и один шаг)
  • Вариант 5: Концепция согласованного хэша — итеративное добавление узлов (для облегчения поэтапной миграции)
  • Вариант 6: концепция согласованного хэша — репозиторий по диапазону (итеративная миграция)

автор

Дзидзо Кельвин

Общественный номер: Кшитигарбха думает

план выбора


Вариант 1: Берём по модулю Ключа, а делитель постепенно увеличиваем

image

Формула: key mod x (x — натуральное число)

Ключ может быть первичным ключом, номером заказа или идентификатором пользователя, это необходимо определить в соответствии со сценарием, какой из них используется больше как вероятность условия запроса.

преимущество:

  • Добавляйте библиотеки и таблицы по мере необходимости и постепенно увеличивайте
  • Равномерно распределены, каждая часть имеет небольшую разницу

недостаток:

  • Во многих случаях она будет разделена на две библиотеки и постепенно увеличивается с 2, а затем делится на 3, 4 и 5. Например, когда мод 3 изменяется на мод 5, результаты по модулю большинства данных после модуля изменятся. Например, когда ключ = 3, мод 3 = 0 и внезапно меняется на мод 5 = 3, он изменится Перенос таблицы 0 в таблицу 3 приведет к многократному перемещению большого количества данных.
  • Данные будут многократно переноситься. При разделении на 2 данные A будут в таблице 0, при разделении на 3 данные A попадут в таблицу 1, а при разделении на 4 данные A вернутся в таблицу 0.

Вариант 2: разделить по времени

Это может быть ежедневно, ежемесячно или ежеквартально.

tb_20190101
tb_20190102
tb_20190103
……

Этот алгоритм требует добавления года, месяца, дня или метки времени к номеру заказа и идентификатору пользователя или добавления года, месяца и дня в интерфейс запроса, чтобы определить, какой сегмент.

преимущество:

  • Данные непрерывны во времени
  • Более интуитивно видеть рост данных

недостаток:

  • Учитывая, что исторические данные не делятся в начале на базы данных и таблицы, порядковый номер исторических данных не обязательно имеет отметку времени, и исторические данные могут быть распределены первичными ключами, полученными из самоинкрементных или пользовательских алгоритмов, что приводит к запросам. Когда вышестоящая система должна передать номер заказа и время создания двух полей.
  • Если вышестоящая система не передает время или время создания вышестоящей системы не совпадает с днем ​​создания соответствующего заказа в текущей системе, запись данных текущей таблицы базы данных должна иметь время поле. Поскольку вышестоящая система передает только номер заказа, в это время необходимо получить время создания Текущая система должна иметь основную таблицу для поддержания взаимосвязи между номером заказа и временем создания, и каждый раз, когда делается запрос, сначала нужно проверить основную таблицу текущей системы, а затем конкретную таблицу, которая потребляет производительность.
  • Распределение не обязательно равномерно: ежемесячные данные о росте не совпадают, некоторые месяцы могут быть больше, а некоторые меньше.

Рекомендуемый сценарий использования: ведение журнала


Вариант 3: По диапазону значений

image

表0 [0,10000000) 
表1 [10000000,20000000)
表2 [20000000,30000000)
表3 [30000000,40000000)
……

преимущество:

  • равномерно распределены

недостаток:

  • Поскольку максимальное значение неизвестно, временная метка не может использоваться в качестве ключа.Этот метод не может использовать самоувеличивающийся первичный ключ таблицы, так как самоувеличивающееся количество каждой таблицы не поддерживается единообразно. Следовательно, должен быть эмитент или система эмитента для поддержки места, где ключи увеличиваются равномерно.

В последующих рекомендуемых решениях давайте кратко поговорим о хэше согласованности.

Давайте сначала поговорим о хэше согласованности.В некоторых статьях говорится, что хэш согласованности — это алгоритм.Я не думаю, что это конкретная формула расчета, а заданная идея.

1. Сначала предположим, что есть кольцевое хэш-пространство, в кольце фиксированы максимальное и минимальное значения, а голова и хвост соединены в замкнутый цикл, например, максимальное и минимальное значения int и long. Многие статьи предполагают 2 ^ 32 позиции, максимальное значение 2 ^ 32-1, а минимальное значение 0, то есть цифровое пространство 0 ~ (2 ^ 32) - 1. Они просто следуют обычно используемому алгоритму хеширования. Например, это число не используется в случае таблиц, поэтому я думаю, что последовательный алгоритм хеширования на самом деле является концепцией, а не реальной формулой расчета. Как показано ниже

image
2. Разработайте значение функции формулы = хэш (ключ), эта формула будет иметь максимальное значение и минимальное значение, например ключ по модулю 64 = значение; максимальное значение этой формулы равно 64, а минимальное значение равно 0. Затем поместите все данные на кольцо.

image
3. Установите узел node. Способ установки узла — это хеширование IP-адреса или настройка фиксированного значения (последующее решение — использовать фиксированное значение). Затем узел идет против часовой стрелки, пока не появится предыдущий узел, и все данные, проходящие через value=hash(key), принадлежат этому узлу. Например, хеш(узел1)=10, тогда данные хэш(ключ)=0~10 управляются узлом1.

image

обобщать

Эта теория здесь подробно не объясняется.В основном это означает, что максимальное значение фиксируется, а диапазон от максимального значения до минимального значения больше не изменяется.Позднее изменяется только положение узла узла и узел добавлено, чтобы уменьшить объем данных, которыми должен управлять каждый узел, чтобы уменьшить нагрузку.

备注:
* 不推荐对ip进行hash,因为可能会导致hash(ip)得出的结果很大,例如得出60,若这个节点的前面没有节点,则60号位置的这个节点需要管大部分的数据了。
* 最好生成key的方式用雪花算法snowFlake来做,至少要是不重复的数字,也不要用自增的形式。
* 推荐阅读铜板街的方案 订单号末尾添加user%64

Вариант 4: Концепция согласованного хеширования — решение для среднего распределения

Используя непротиворечивую теорию хеширования, эталоном формулы для хэша выбора подбазы данных (ключа) является значение = ключ по модулю 64, значение формулы подтаблицы = ключ / 64 по модулю 64, а ключ является основным полем, которое часто запрашивается, например как номер заказа или идентификатор пользователя. (Последующие изменения в эту формулу будут внесены) Принимая приведенную выше формулу, его можно разделить на 64 банка, каждый банк имеет 64 таблицы, предполагая таблицу с 10 миллионами строк записей. Тогда максимальные данные 64*64*10 миллионов, я считаю, что этот день не наступит, поэтому нам разумнее использовать это как максимальное значение, даже 32*32 можно выбрать.

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

分组公式:64 = 每组多少个count  * group需要分组的个数 
数据所在环的位置(也就是在哪个库中):value = key mode 64 / count  * count  

В следующем примере 16 групп, то есть 16 библиотек, группа = 16. В это время формула библиотеки значение = режим ключа 64 / 4 * 4. После деления на 4 десятичный знак будет перехвачен для получения целого числа, а затем * 4 раза, что является расположением данных.

// 按4个为一组,分两个表
count = 4:
Integer dbValue = userId % 64 / count * count ;

image

hash(key)在0~3之间在第0号库
hash(key)在4~7之间在第4号库
hash(key)在8~11之间在第8号库
……

Примечания: На самом деле группа из 64 может быть вначале одной библиотекой, а затем группа из 32 может быть двумя библиотеками, от одной библиотеки к двум библиотекам, а затем к 4 библиотекам, постепенно увеличиваясь.

Итерация расширения из подбиблиотеки:

image

image

image

На следующем рисунке после того, как пример разделен на группы 16, он становится разделенным на группы 32. Каждой библиотеке необходимо вынуть половину данных, чтобы перейти к новым данным, и расширить емкость, пока она не будет разделена на 64 группы.

image

Видно, что когда емкость необходимо удвоить, необходимо перенести половину данных с шагом 2^n, поэтому масштаб влияния будет относительно большим.

преимущество:

  • Если сразу разделить 32 группы, то это будет сделано раз и навсегда
  • Если объем данных относительно велик, вы можете использовать метод раз и навсегда, если вы не сделали подтаблицу.
  • равномерно распределены
  • При переносе данных нет необходимости переноса большей части данных и повторных миграций, как в схеме 1, требуется перенос только половины данных

недостаток:

  • Его можно расширить, но сфера влияния велика.
  • Объем переносимых данных относительно велик. Хотя он не так велик, как при переносе большей части данных в первом решении, текущее решение требует переноса половины данных для каждой таблицы или базы данных.
  • Чтобы сделать это раз и навсегда, требуется общее время простоя для переноса данных.

Вариант 5: концепция согласованного хеширования — итеративное увеличение узлов

(думаю лучшее решение)

Схема согласованного хеширования сочетается со схемой диапазона сравнения, то есть комбинацией схемы три и схемы четыре.

Анализ четвертой проблемы

Вариант 4 — установить максимальный диапазон 64 и увеличить количество баз данных или таблиц с 1 в виде экспоненты 2 ^ n. Это дает около 1/2 общего объема данных при переносе каждого разделения. большой, так что либо он сразу разбивается на 32 группы и 64 группы раз и навсегда, либо мигрируется 1/2 каждого раза.

Схема 4 соответствует схеме миграции:

  1. Первый — остановить миграцию данных, а после успеха перезапустить сервер. Влияет на всех пользователей в течение длительного времени.
  2. Во-вторых, переключить источник данных на подчиненную базу данных, предоставить пользователям доступ только для чтения, перенести данные из основной базы данных, а затем после успеха переключиться на основную базу данных, хотя пользователь может применить ее, это повлияет на прирост бизнеса.
  3. В-третьих, установить источник данных так, чтобы половина пользователей могла только читать, а другая половина пользователей могла читать и писать в соответствии с правилами.Поскольку миграция схемы 4 затрагивает общие данные, этот метод может быть выполнен максимум .

Подробное объяснение пятого плана

Теперь, когда я думаю о методе, сохраняйте концепцию согласованного хеширования и добавляйте один узел за другим вместо добавления 2 ^ n-n узлов каждый раз в четвертом решении. Но код должен оценивать хэш-значение данных в новом узле.

Мы продемонстрируем последующие итерации на основе того факта, что две библиотеки были разделены за одну итерацию.Сначала давайте рассмотрим ситуацию, когда две библиотеки были разделены:

Данные попадают на 64-ю библиотеку с именем db64 и 32-ю библиотеку с именем db32

image


Итерация вторая: Разница и решение 4 напрямую добавляют два узла Мы добавляем только один узел Таким образом, при переносе данных будет затронута 1/2 пользователей, и будет затронута только 1/4 пользователей.

image
В коде мы сначала меняем группировку с группы из 32 на группу из 16, а затем придаем коду особую обработку. 0~16 перейти к новому узлу 16~32 вернуться к исходному узлу 32 32~63 вернуться к исходному узлу 64 Итак, ниже приведен специальный if else для узла

// 按32改为16个为一组,分两变为4个库
count = 16;
Integer dbValue = userId  % 64 / count * count ;
if(dbValue<16){
    // 上一个迭代这些数据落在db32中,现在走新增节点名为db16号的那个库
    dbValue =  16;
    return dbValue;
} else {
    // 按原来规则走
    return dbValue;
}

Итерация третья:

image
Таким образом, четыре раунда миграции четырех схем могут быть выполнены итеративно.

Перед миграцией вы можете сначала подключиться к сети, добавить код переключения и запросить интерфейс, чтобы он специально обрабатывал номер заказа или номер пользователя, хеш-значение которого меньше 16, так что это затронет только 1/4 людей.

// 在请求接口中增加逻辑
    public void doSomeService(Integer userId){
        if(迁移是否完成的开关){
            // 如果未完成
            Integer dbValue = userId  % 64 / count * count ;
            if(dbValue<16){
                //这部分用户暂时不能走下面的逻辑
                return ;
            }
        }
        return dbValue;
    }
}
// 在分片时按32个为一组,分两个库
count = 16;
Integer dbValue = userId  % 64 / count * count ;
if(dbValue<16){
    // 上一个迭代这些数据落在db32中,有一半需要走新增节点名为db16号的那个库
    if(迁移是否完成的开关){
        // 如果已经完成,就去db16的库
        dbValue =  16;
    }
    return dbValue;
} else {
    // 按原来规则走
    return dbValue;
}

По аналогии, когда в следующем раунде всего 8 узлов, необходимо мигрировать только 1/8 каждой миграции.

На самом деле, в первой итерации вы можете сделать это, не выбирая значение dbValue меньше 16. Непосредственно сгруппируйте 8 в группы и выберите только dbValue

преимущество:

  • легко расширить
  • В процессе постепенного увеличения данных медленно увеличивайте узлы
  • Влияет на небольшое количество пользователей
  • Работайте итеративно, чтобы снизить риск
  • Короткое время миграции, например гибкое итеративное мышление

недостаток:

  • неравномерно во времени

Вариант 6: концепция согласованного хэша — репозиторий по диапазону (итеративная миграция)

Подобно тому, как вышеупомянутая схема 5 является схемой 4 + схема 1, которая может обеспечить постепенную миграцию данных, существует и другая схема. Это схема 4 + схема 3, но ее не нужно группировать по модулю.

userId % 64 / count * count

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

 第一片 0<userId  % 64<15
 第二片 16<userId  % 64<31
 第三片 32<userId  % 64<47
 第四片 48<userId  % 64<63

Конечно, диапазон можно настроить, чтобы увидеть, какое значение следует за модулем больше, просто вырежьте определенный кусок данных, а не рисуйте конкретную картинку, которая аналогична схеме 4.

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

Однако в случае бизнес-приоритета бизнес все время итерируется, как только данных поступает много, когда 16 веток тоже много данных, мы можем использовать концепцию последовательного хэша — разделить базу данных по к диапазону


Добро пожаловать, чтобы следовать

Мой публичный номер: Кшитигарбха думает

地藏思维

Самородки: Дзидзо Кельвин

Краткая книга: Кельвин Кельвин

CSDN: Дзидзо Кельвин

Моя одежда: Дзидзо Кельвинgit ee.com/jizo-consider…