Как я могу спроектировать систему, которая обрабатывает 100 тыс. запросов в секунду в пиковое время, при этом каждый запрос выполняет обновление объекта размером 20 КБ?
Я использовал nodejs в качестве бэкэнда для неблокирующего ввода-вывода, шаблон с отложенной записью с redis в качестве кеша и mongodb в качестве базы данных, но на пике он обрабатывает только 10 тыс. запросов в секунду.
предположим, что инфраструктура - это только мой компьютер: процессор, 4 ядра, 8 потоков, 16 ГБ оперативной памяти, есть ли другой способ оптимизировать производительность моей системы
Что ж, вам необходимо приобрести или арендовать серверы, эффективно предназначенные для этих задач. Потому что вам нужно купить 14 компьютеров или больше, потому что ПК неэффективны. Возможно, вы сможете найти бывшие в употреблении серверы. Но на одном компьютере это сделать невозможно. 10К - это слишком далеко от 100К.
Я не эксперт в этом, но процессоры массового ПК AFAIK на самом деле не предназначены для этого, и десятки Kreq/s кажутся нормальными, ИМХО, на такой машине. 100Kreq означает, что требуется <40 мкс на ядро, что довольно мало для используемого вами инструмента, и несколько системных вызовов, каждый из которых обычно занимает несколько мкс на основных процессорах. Я думаю, вы можете достичь такой производительности с помощью высокооптимизированных собственных инструментов, использующих оптимизированные API-интерфейсы ОС (что часто означает меньше функций, более высокую сложность и более высокие затраты на обслуживание). Вы можете определить узкие места, чтобы немного расширить лимит, но, конечно, не в 10 раз.
Это требование, вероятно, должно было быть в верхней части списка соображений при проектировании системы. Вы можете попробовать написать простую «базу данных» на основе ключей и значений на таком быстром языке, как c. Если вы сможете кэшировать достаточное количество данных в оперативной памяти, вы сможете обновлять объекты с пиковой скоростью, исчисляемой миллионами в секунду, на одном скромном ПК, как только у вас будет работа в памяти. Получение работы через сокет TCP также может сильно замедлить работу. Я не знаю, чего вам следует от этого ожидать.
Если ваших аппаратных ресурсов достаточно, но вы хотите оптимизировать свое приложение, вы можете рассмотреть некоторые из приведенных ниже методов.
Модуль кластера: используйте модуль кластера nodejs, чтобы получить некоторые преимущества многоядерной системы. Это позволит вам создать несколько экземпляров вашего приложения, каждый из которых работает на ядре ЦП.
Рабочий: для задачи ресурсоемких операций (с привязкой к процессору) рассмотрите возможность использования рабочих потоков, это может разделить задачу на несколько потоков, что позволит создать основной цикл событий, отвечающий за другую асинхронную задачу.
Менеджеры заданий: вы можете использовать менеджеров заданий, таких как Bull, чтобы выполнять некоторые операции в фоновом режиме, добавляя их в очередь.
сжатие: вы можете использовать технику сжатия, чтобы уменьшить размер данных, используйте хороший алгоритм сжатия, например Gzip или Brotli.
Вам необходимо балансировать нагрузку и масштабировать по горизонтали. См. также здесь. Вам нужно 2 балансировщика нагрузки и, возможно, 14 «обычных» серверов для обработки 100 тысяч запросов.