Выдержать 10 миллиардов запросов? давай попробуем

задняя часть сервер HTTPS

Выдержать 10 миллиардов запросов? давай попробуем

Автор: ppmsn2005#gmail.com
проект:GitHub.com/miniholiday/1…
wiki: GitHub.com/miniholiday/1…

1. Введение


Несколько дней назад я наткнулся на книгу «Удерживание 10 миллиардов запросов — как создать «безопасную» систему красных конвертов для гала-концерта весеннего фестиваля» ([url](http://www.infoq.com/cn/presentations/how-to). -построить-весенний-фестиваль-бонусная-система)) Прочитав статью, я испытал массу эмоций и получил много пользы.Как так называемый камень других гор можно использовать для атаки нефрита, хотя эта статья была опубликовано в 2015 году, я видел Это уже конец 2016 года, но идеи в нем все еще можно использовать для ознакомления во многих back-end проектах.В то же время, как инженер, после прочтения этой статьи, я буду думать о может ли это привнести какую-то практичность в мою работу после прочтения такой статьи.А как насчет вашего опыта?Говорят,что то, что выучено на бумаге-это поверхностно,и вы ничего об этом не знаете.Можете ли вы сами попрактиковаться в 10 миллиардах запросов в красных конвертах? Иначе после прочтения в голове останется что-то. Но это слова 10 миллиардов 14 миллионов QPS исправление, остальная часть статьи покажет, как автор нацеливает этот процесс и моделирует этот процесс в локальной среде.

  Достигнутые цели: одна машина поддерживает 1 миллион подключений, имитирует процесс встряхивания красных пакетов и отправки красных пакетов, а пиковое число запросов в секунду одной машины составляет 60 000, что обеспечивает бесперебойную работу бизнеса.

Примечание: эта статья и все содержание автора представляют собой только личное понимание и практику.Процесс не имеет ничего общего с командой WeChat, и реальная онлайн-система также отличается.Это практикуется только с некоторых технических моментов, пожалуйста, различайте читатели. Из-за ограниченного уровня автора, любые вопросы являются ответственностью автора.Если у вас есть какие-либо вопросы, пожалуйста, свяжитесь с ppmsn2005#gmail.com.Выдержать 10 миллиардов запросов? давай попробуем

2. Базовые знания


  QPS: запросов в секунду Количество запросов в секунду

  PPS: Пакетов в секунду Количество пакетов в секунду

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

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

3. Ставьте цели


  Прежде чем запускать все системы, мы должны выяснить, какая грузоподъемность должна быть у нашей системы после завершения.
##3.1 Общее количество пользователей:
Из статьи мы можем узнать, что существует 638 серверов доступа, а верхний предел службы составляет около 1,43 миллиарда пользователей, поэтому верхний предел пользователей для загрузки одного сервера составляет около 1,43 миллиарда / 638 единиц = 2,28 миллиона пользователей / Блок. Но в настоящее время в Китае точно не будет 1,4 миллиарда пользователей онлайн одновременно, см.enterprise.forward.com/show/detail…В 2016 году количество пользователей WeChat во втором квартале составляло около 800 миллионов, а ежемесячная жизнь — около 540 миллионов. Поэтому во время Праздника Весны в 2015 году пользователей хоть и будет много, но онлайн точно будет меньше 540 миллионов одновременно.
##3.2 Количество серверов:
   Всего серверов 638. Согласно плану нормальной эксплуатации и обслуживания, я полагаю, что все серверы не будут полностью подключены к сети, и будет определенное резервирование оборудования для предотвращения внезапных отказов оборудования. Предположим, что всего имеется 600 серверов доступа.
##3.3 Количество нагрузок, которые должна поддерживать одна машина:
   Количество пользователей, поддерживаемых каждым сервером: 540 миллионов/600 = 900 000. То есть в среднем одна машина поддерживает 900 000 пользователей. Если реальный случай превышает 900 000, смоделированный случай может быть необъективным, но я думаю, что QPS важнее в этом эксперименте.

3.4. Автономные пиковые QPS:

В статье четко указано, что это 14 миллионов запросов в секунду. Это значение очень велико, но поскольку серверов 600, количество запросов в секунду для одной машины составляет 14 миллионов / 600 = около 23 000 запросов в секунду. В статье однажды упоминалось, что система может поддерживать 40 запросов в секунду. миллионов QPS , то количество QPS системы должно быть не менее 40 миллионов/600 = около 66 000, что примерно в 3 раза превышает текущее значение и в ближайшее время не изменится. Но я считаю, что соответствующий стресс-тест должен быть сделан.

3.5. Раздача красных конвертов:

В статье упоминается, что система выдает 50 000 штук в секунду, тогда одномашинная скорость доставки в секунду 50 000/600 = 83 штуки в секунду, то есть одномашинная система должна обеспечивать скорость доставки 83 штук в секунду.
   Наконец, учитывая подлинность системы, есть, по крайней мере, действия пользователей по входу в систему и такие предприятия, как получение красных конвертов. Реальная система также будет включать в себя такие службы, как чат.

Наконец, давайте посмотрим на требование в 10 миллиардов встрясок красных конвертов в целом.Предполагая, что это происходит равномерно в течение 4 часов гала-концерта Весеннего фестиваля, тогда QPS сервера должен быть 10000000000/600/3600/4.0=1157. то есть один сервер в секунду Более 1000 раз, это значение на самом деле невелико. Если он полностью обработан пиковой скоростью 14 миллионов, 10000000000/(1400*10000) = 714 секунд, что означает, что для выполнения всех запросов пиковой скорости требуется всего 11 минут. Можно видеть, что одной из характеристик интернет-продуктов является то, что пиковое значение очень велико, а продолжительность не очень велика.

Суммировать:

  С одного сервера. Он должен соответствовать следующим условиям
  1. Поддержка не менее 1 миллиона подключенных пользователей
   2. В секунду может обрабатываться не менее 23 000 запросов в секунду, здесь мы устанавливаем более высокую цель, установленную на 30 000 и 60 000 соответственно.
3. Встряхивание красных конвертов: он поддерживает раздачу красных конвертов со скоростью 83 в секунду, что означает, что имеется 23 000 запросов встряхивания красных конвертов в секунду, из которых 83 запроса могут получить красные конверты, а остальные 22 900 запросов будут знать чтобы они их не качали. Конечно, после того, как клиент получит красный конверт, ему также необходимо убедиться, что количество красных конвертов с обеих сторон клиента и сервера совпадает с количеством в красном конверте. Из-за отсутствия платежного модуля мы также удваиваем требования для достижения скорости раздачи 200 красных пакетов в секунду.
  4. Поддерживайте бизнес по отправке красных конвертов между пользователями и следите за тем, чтобы количество красных конвертов с обеих сторон отправки и получения и сумма в красных конвертах были одинаковыми. Мы также установили скорость распространения 200 красных пакетов в секунду в качестве нашей цели.

  Симулировать всю систему полностью слишком сложно, во-первых, это требует большого количества серверов, а во-вторых, требует сотни миллионов симулированных клиентов. Для меня это невозможно, но одно можно сказать наверняка, всю систему можно масштабировать по горизонтали, поэтому мы можем смоделировать 1 миллион клиентов, а при моделировании сервера мы выполнили 1/600 симуляции.

Отличия    от существующей системы:
   В отличие от большинства тестов с высоким QPS, эта система фокусируется на другом. Я сделал несколько сравнений между ними.

Общие стресс-тесты системы с высоким количеством запросов в секунду стресс-тест системы
количество подключений Обычно 1 000 000 (1 миллион)
Пропускная способность одного соединения Очень большая пропускная способность в десятки мегабайт на соединение Очень маленькие десятки байт каждый раз
требуемое время ввода-вывода немного Много

№ 4. Базовое программное и аппаратное обеспечение
##4.1 Программное обеспечение:
  Golang 1.8r3, оболочка, python (Разработка не использовала c++, а использовала golang, потому что первоначальный прототип с использованием golang соответствовал системным требованиям. Хотя у golang все еще есть некоторые проблемы, по сравнению с эффективностью разработки, эта потеря приемлема)
  Серверная ОС:
  Убунту 12.04
  Клиентская ОС:
  дебиан 5.0
##4.2 Аппаратная среда   Сервер: dell R2950. 8-ядерная физическая машина, неисключительно работающая с другими предприятиями, память 16G. Это оборудование около 7 лет назад, и производительность не должна быть очень требовательной.
  Версия аппаратного обеспечения сервера:
machine
  Информация о процессоре сервера:
cpu

  Клиент: виртуальная машина esxi 5.0, настроенная на 4 ядра и память 5G. Всего имеется 17 единиц, каждая из которых устанавливает 60 000 соединений с сервером. Выполните 1 миллион клиентских симуляций

5. Технический анализ и реализация


## 5.1) Одна машина для достижения 1 миллиона подключений пользователей    Это относительно просто Автор завершил разработку и эксплуатацию одной машины с миллионами пользователей несколько лет назад. Современные серверы могут поддерживать миллионы пользователей. Для связанного контента вы можете просмотреть код   github и соответствующие документы.
https://github.com/xiaojiaqi/C1000kPracticeGuide
  Документы по конфигурации и оптимизации системы:
https://github.com/xiaojiaqi/C1000kPracticeGuide/tree/master/docs/cn

5.2) 30 000 запросов в секунду

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

Число запросов в секунду клиента

   Поскольку к серверу подключен 1 миллион, количество запросов в секунду составляет 30 000. Это означает, что каждые 33 секунды для каждого соединения на сервер необходимо отправлять запрос на встряхивание красного конверта. Поскольку количество подключений, которые может установить один IP-адрес, составляет около 60 000, существует 17 серверов, которые одновременно имитируют поведение клиента. Все, что нам нужно сделать, это обеспечить отправку такого количества запросов на сервер каждую секунду.
Технический момент — сотрудничество на стороне клиента. Однако время запуска каждого клиента и время установления соединения несовместимы, и существуют такие ситуации, как отключение и повторное подключение к сети.Как каждый клиент определяет, когда ему нужно отправить запрос и сколько запросов должен отправить каждый?

   Я решил это так: используйте службу NTP для синхронизации всего времени сервера, а клиент использует метку времени, чтобы определить, сколько запросов ему нужно отправить в это время.
Алгоритм    легко реализовать:
Предполагая, что имеется 1 миллион пользователей, идентификатор пользователя равен 0-999999. Требуемое количество запросов в секунду составляет 50 000, клиент знает, что количество запросов в секунду составляет 50 000, а общее количество пользователей равно 1 миллиону, он вычисляет 1 миллион / 50 000 = 20, все пользователи должны быть разделены на группы 20. Если time() % 20 == id пользователя % 20, то пользователь с этим id должен сделать запрос в эту секунду, тем самым реализуя многоклиентскую совместную работу. Каждому клиенту нужно знать только общее количество пользователей и число запросов в секунду, чтобы самостоятельно делать точные запросы.
(Расширенное мышление: что, если число запросов в секунду равно 30 000, число, которое нельзя разделить поровну? Как обеспечить максимально сбалансированное количество запросов, отправляемых каждым клиентом?)

###Серверный QPS    Серверный QPS относительно прост, ему нужно только обработать запрос клиента. Но чтобы объективно понять ситуацию с процессингом, нам нужно сделать 2 вещи.
  Во-первых: вам нужно записать количество запросов, обрабатываемых в секунду, что требует встраивания счетчика в код.
  Второе: Нам нужно следить за сетью, потому что пропускная способность сети может объективно отражать реальные данные QPS. С этой целью я использовал скрипт Python в сочетании с инструментом ethtool, чтобы написать простой инструмент, с помощью которого мы можем визуально отслеживать, как пакеты данных проходят через сеть. Это может объективно показать, что в нашей сети происходит так много передачи данных.
Скриншот инструмента:工具截图

5.3) Встряхивание красных конвертов

   Дело встряхивания красных пакетов очень простое.Во-первых, сервер производит красные пакеты с определенной скоростью. Если красный конверт не забрать, он свалится внутрь. Сервер получает запрос от клиента, если на сервере есть красный конверт, он сообщит клиенту, что красный конверт есть, иначе подскажет, что красного конверта нет.
   Поскольку на один компьютер поступает 30 000 запросов в секунду, большинство запросов не выполняются. Осталось решить проблему с замком.
Для того, чтобы уменьшить конкуренцию, я разделил всех пользователей в разные ведра. Это снижает конкуренцию за замки. Если в будущем появятся более высокие требования к производительности, вы также можете использовать высокопроизводительную очередь — Disruptor для дальнейшего повышения производительности.

   Обратите внимание, что в моей тестовой среде отсутствует основная услуга оплаты, поэтому сложность реализации значительно снижается. Приводится другой набор цифр: пик двойных 11 транзакций Taobao в 2016 году составлял всего 120 000 в секунду, а скорость распространения красных конвертов WeChat составляла 50 000 в секунду. Сделать это очень сложно. (Каждый день.SOHU.com/20161111/you4…

##5.4) Бизнес по отправке красных конвертов    Бизнес по отправке красных конвертов очень прост.Система случайным образом генерирует несколько красных конвертов и случайным образом выбирает некоторых пользователей.Система подсказывает этим пользователям, что есть красные конверты. Этим пользователям нужно только отправить запрос на разделение красного конверта, и система может случайным образом разделить часть суммы из красного конверта и раздать ее пользователю для завершения дела. Здесь также нет оплаты за эту основную услугу.

5.5) Мониторинг

   Напоследок нужна система мониторинга для понимания состояния системы, я позаимствовал из другого своего проекта (GitHub.com/Маленький праздник/Пост…) часть кода завершает этот модуль мониторинга.С помощью этого мониторинга сервер и клиент будут отправлять текущее содержимое счетчика в мониторинг.Мониторинг должен интегрировать и отображать данные каждого клиента. В то же время журнал будет записан, чтобы предоставить необработанные данные для будущего анализа. Онлайн-системы используют больше баз данных временных рядов, таких как opentsdb, где ресурсы ограничены, поэтому используется оригинальное решение.

Мониторинг показывает, что лог выглядит так
监控日志

№ 6. Реализация и анализ кода

   С точки зрения кода, здесь используется не так много навыков, в основном необходимо учитывать дизайнерские идеи и некоторые проблемы самого golang.
Во-первых, в golang контролируется количество горутин, так как соединений минимум 1 миллион, то по обычной схеме проектирования для работы требуется минимум 2 или 3 миллиона горутин. Это ложится тяжелым бременем на саму систему.
Во-вторых, управление 1 миллионом подключений, будь то подключение или бизнес, это вызовет некоторую умственную нагрузку.
Мой дизайн такой:

架构图

   Сначала разделите 1 миллион соединений на несколько разных SET, каждый SET является независимым параллельным объектом. Каждый SET управляет только несколькими тысячами подключений, и если один SET работает нормально, мне просто нужно добавить SET, чтобы увеличить вычислительную мощность системы. Есть еще одно преимущество деления по SET.SET можно использовать как бизнес-единицу, а на серверы с разной производительностью можно нагружать разные нагрузки.Например, 8-ядерная машина управляет 10 SET, а 4-ядерная машина управляет 5 комплектами. Можно распределить давление мелкозернистого распределения. , и легко мигрировать
   Во-вторых, размер структуры данных в каждом SET тщательно разработан, чтобы гарантировать, что давление каждого SET не будет слишком большим, и не будет накапливаться сообщений.
   Снова уменьшено количество грутин, каждое соединение использует только одну горутину, и только одна гкроутина отвечает за отправку сообщений в SET, что экономит 1 миллион горутин. Таким образом, вся система должна поддерживать Один миллион и сотни грутинов могут завершить дело. Большая экономия процессора и памяти
Рабочий процесс системы    примерно следующий:
После успешного подключения каждого клиента система назначит горутину для чтения сообщения клиента.Когда сообщение будет прочитано, оно будет преобразовано в объект сообщения и помещено в очередь получения сообщений в SET, а затем вернется для получения следующего сообщение
  Внутри SET есть работающая горутина, она делает очень простые и эффективные вещи, она делает следующее, проверьте сообщение о принятии SET, она получит 3 типа сообщений

1. Сообщение запроса клиента в красном конверте

2. Другие сообщения от клиента, например, общение с друзьями

3. Сервер отвечает на сообщение клиента

Для первого типа сообщения клиентское сообщение с запросом в красном конверте обрабатывается следующим образом.Получите сообщение с запросом в красном конверте от клиента, попытайтесь получить красный конверт из очереди красных конвертов SET и верните информацию о красном конверте в клиент, если вы его получили, в противном случае Создайте сообщение, которое не было встряхнуто, и верните его соответствующему клиенту.
   Для второго типа сообщения другие сообщения клиента, такие как друзья по чату, просто берут сообщение из очереди и пересылают его в очередь внутренней службы чата, а другие службы пересылают сообщение.
   Для третьего сообщения сервер отвечает на сообщение клиента. SET нужно только найти объект подключения пользователя, зарезервированный в SET в соответствии с идентификатором пользователя в сообщении, и отправить его обратно.

   Для службы генерации красных конвертов ее работа очень проста, просто нужно по очереди в столбце генерации красных конвертов каждого SET по очереди и последовательно помещать его в объект красного конверта. Это может гарантировать, что каждый SET будет честным, а во-вторых, его интенсивность работы очень низкая, что может обеспечить стабильность бизнеса.

см. код
GitHub.com/miniholiday/1…

7 Практика


Процесс практики делится на 3 этапа

##Этап 1: Запустите серверную сторону и сторону мониторинга соответственно, а затем запустите 17 клиентов один за другим и дайте им установить 1 миллион ссылок. На стороне сервера используйте команду ss, чтобы подсчитать, сколько соединений каждый клиент установил с сервером.
Команда выглядит следующим образом:
Alias ss2=Ss –ant | grep 1025 | grep EST | awk –F: “{print $8}” | sort | uniq –c’

Результат выглядит следующим образом:100万连接建立

##Этап 2. С помощью http-интерфейса клиента настройте число запросов в секунду для всех клиентов на 30 000 и позвольте клиенту отправлять запрос с интенсивностью запросов в секунду 3 Вт.
Выполните следующую команду:
启动脚本

Наблюдайте за сетевым мониторингом и мониторингом обратной связи терминала и обнаружите, что QPS достигает ожидаемых данных.
Скриншот мониторинга сети
3万qps

Запустите службу, которая генерирует красные пакеты на стороне сервера.Эта служба будет выдавать красные пакеты со скоростью 200 в секунду, всего 40 000 красных пакетов. В это время, просматривая логи клиента на мониторинге, вы обнаружите, что красные конверты в основном получаются со скоростью 200 в секунду.

![Встряхните красный конверт] (Пользовательское содержимое raw.GitHub.com/miniholiday/1…)

После того, как все красные конверты будут выпущены, запустите службу красных конвертов.Эта система службы будет генерировать 20 000 красных конвертов, 200 в секунду.Каждый красный конверт случайным образом назначает 3 пользователей и отправляет сообщение этим 3 пользователям.Клиент автоматически придет, чтобы получить красные конверты, и, наконец, все красные конверты убраны.

发红包

Этап 3

Используйте http-интерфейс клиента, чтобы настроить количество запросов в секунду для всех клиентов на 60 000, и позвольте клиенту отправить запрос с интенсивностью 6W QPS.

6wqps

Таким же образом на стороне сервера запустите службу, которая генерирует красные пакеты, и эта служба будет отправлять красные пакеты со скоростью 200 в секунду. Всего 40 000. В это время, просматривая логи клиента на мониторинге, вы обнаружите, что красные конверты в основном получаются со скоростью 200 в секунду.
После того, как все красные конверты будут выпущены, запустите службу красных конвертов.Эта система службы будет генерировать 20 000 красных конвертов, 200 в секунду.Каждый красный конверт случайным образом назначает 3 пользователей и отправляет сообщение этим 3 пользователям.Клиент автоматически придет, чтобы получить красные конверты, и, наконец, все красные конверты убраны.

Наконец, практика сделана.

# 8 Анализ данных
На практике и сервер, и клиент отправляют на терминал мониторинга записи собственных внутренних счетчиков, которые становятся логами. Мы используем простой скрипт Python и инструмент построения графиков gnuplt, чтобы визуализировать процесс на практике, чтобы проверить его выполнение.

Первый - это данные отправки QPS клиента.
客户端qps
Абсцисса этой картинки — время, единица измерения — секунды, а ордината — QPS, что указывает на QPS запросов, отправленных всеми клиентами в данный момент.
Первый интервал между цифрой, несколько небольших пиков, - это 1 миллион установленных клиентом соединений, а вторая часть фигуры - 30 000 интервалов QPS, мы можем видеть данные Стабильнее поддерживать диапазон в 30000. Наконец, диапазон 60 000 запросов в секунду. Но по всей карте видно, что QPS не идеально держится на нашей ожидаемой линии. В основном это связано со следующими причинами

  1. Когда одновременно выполняется множество горутин, полагаться на время сна нельзя, и возникает смещение. Я думаю, что это вызвано собственным расписанием golang. Конечно, если процессор относительно сильный, это явление исчезнет.
  2. Из-за влияния сети, когда клиент инициирует соединение, может возникнуть задержка, в результате чего соединение не будет установлено в течение первой 1 секунды.
  3. Когда нагрузка на сервер велика, сеть 1000M уже теряет пакеты, что можно наблюдать с помощью команды ifconfig, поэтому будут колебания QPS.

Вторая — карта QPS, обрабатываемая сервером.
服务器qps

В соответствии с направлением клиента сервер также имеет три интервала, которые очень близки к ситуации клиента. Но мы видим, что примерно в 22:57 вычислительная мощность системы имеет значительный спад, а затем резко возрастает. Это показывает, что код все еще нуждается в оптимизации.

Общее наблюдение находится в диапазоне 30 000 запросов в секунду, а количество запросов в секунду сервера относительно стабильно, при 60 000 QSP обработка сервера нестабильна. Я считаю, что это как-то связано с моим кодом, и если я продолжу его оптимизировать, результат должен быть лучше.

Объединить 2 картинкиqps

В основном он непротиворечив, что также доказывает, что система соответствует ожидаемому дизайну.

Это диаграмма изменения состояния количества сгенерированных красных пакетов.
生成红包

очень стабильно.

Это статус красного конверта, получаемый клиентом каждую секунду
获取红包

Вы можете найти интервалы QPS 30 000. Количество красных конвертов, полученных в секунду, составляет около 200, а при сильном джиттере оно не обязательно будет равно 200. Я думаю, что это в основном 60 000 QPS, джиттер сети усугубляется, вызывая дрожание количества красных конвертов.

Наконец, есть информация о pprof, которая поставляется с golang, в которой время gc превышает 10 мс.Учитывая, что это аппаратное обеспечение 7-летней давности и неэксклюзивный режим, это все еще приемлемо.
pprof

Суммировать:

  В соответствии с целью проектирования мы смоделировали и спроектировали систему, которая поддерживает 1 миллион пользователей и может поддерживать не менее 30 000 запросов в секунду и максимум 60 000 запросов в секунду, просто моделируя процесс красных конвертов WeChat и красных конвертов. Можно сказать, что намеченная цель достигнута.
Если каждый из 600 хостов может поддерживать 60 000 запросов в секунду, для выполнения 10 миллиардов запросов в красных конвертах требуется всего 7 минут.

Хотя этот прототип просто доделывает предустановленный бизнес, чем он отличается от реального сервиса? я перечислил

разница Реальный сервис Это моделирование
сложный бизнес Более сложный очень простой
протокол Protobuf и шифрование простое соглашение
платить сложный никто
бревно сложный никто
представление выше никто
Распределение пользователей Идентификаторы пользователей разбросаны по разным серверам и нуждаются в унификации после хеширования, что сложно. Идентификатор пользователя непрерывен, множество оптимизаций делают код простым и очень эффективным.
безопасно контролировать сложный никто
Горячие обновления и контроль версий сложный никто
монитор дотошный Простой

Относится: