惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
IT之家
IT之家
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Cisco Talos Blog
Cisco Talos Blog
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
J
Java Code Geeks
博客园_首页
Scott Helme
Scott Helme
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
T
The Exploit Database - CXSecurity.com
Security Latest
Security Latest
V
Visual Studio Blog
Cloudbric
Cloudbric
Jina AI
Jina AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
A
Arctic Wolf
C
Cybersecurity and Infrastructure Security Agency CISA
S
SegmentFault 最新的问题
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
W
WeLiveSecurity
K
Kaspersky official blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News: Ask HN
Hacker News: Ask HN
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
量子位
Google Online Security Blog
Google Online Security Blog
博客园 - Franky
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 三生石上(FineUI控件)
Recent Commits to openclaw:main
Recent Commits to openclaw:main

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Race Condition убил SQLite в нашем проекте: как мы пришли к RediSearch
KarimAbushae · 2026-05-13 · via Все публикации подряд на Хабре

Время на прочтение4 мин

Охват и читатели666

Туториал

Мне пришла задача на исследование — выбрать хранилище для промышленной телеметрии. Я раньше с таким вообще не работал. Ни с временными рядами, ни с реактивным программированием, ни с WebSocket. Работал только с Postgres.

Слышал про Redis, но не применял. На выбор — SQLite или Redis, надо исследовать что лучше. Пошёл читать. Нашёл TimescaleDB и ещё кучу вариантов — у каждого свои плюсы.

Основной плюс SQLite — там можно писать запросы, SQL знакомый, Spring интеграция есть. Скорость записи меня вообще удивила — и у Redis, и у SQLite. Я не ожидал таких цифр.

Долго не мог понять зачем вообще Redis, если там нет нормального поиска. Просто хэши ключ-значение. Хочешь найти все датчики по типу объекта — не работает. Я такой: ладно, Redis минус, берём SQLite.

Сделал прототипы. Потестировал один поток — SQLite летит, 370 000 вставок в секунду. Redis ещё быстрее — 650 000. Нашёл RediSearch с поиском по индексам — оч круто, но скорость падает до 150 000. SQLite снова выглядит выигрышнее.

И вот я запускаю 100 потоков на SQLite.

В логах появляется:

org.sqlite.SQLiteException: [SQLITE_BUSY]
The database file is locked

Не один раз. Постоянно. Скорость падает с 370 000 до 98 000 вставок в секунду. Данные теряются.

Я потратил несколько дней на исследование, написал два прототипа, нашёл RediSearch — и в итоге выбирал не по тому критерию. Скорость на одном потоке вообще не важна, когда система параллельная.

Вот тогда я и понял что выбирал не по тем критериям. Делюсь цифрами — чтобы вы не повторили тот же путь.

Задача

Промышленный сервис телеметрии. Данные от датчиков летят через WebSocket и REST. Каждое измерение — тип объекта, ID, ID параметра, момент времени и значение (число, строка или дата).

Нужно:

  • быстро писать — десятки и сотни тысяч вставок в секунду

  • держать параллельную запись от множества потоков

  • искать по типу, ID, диапазону значений

  • хранить последнее значение каждого датчика

Стек — Spring WebFlux, реактивный. Это важно для выбора инструмента.

Два прототипа

Сделал два одинаковых прототипа с одинаковыми данными — один на SQLite, второй на Redis. Просто чтобы пощупать.

Скорость записи SQLite на диске с WAL — 370 000 вставок/сек. Я не ожидал такого от файловой базы.

Скорость записи Redis (чистый HSET, без индексов) — 650 000 вставок/сек. Redis работает в памяти, поэтому понятно почему так.

Но поиска в Redis нет. Просто HSET cur:1:100:5 value 42.5 — и всё. Хочешь найти все датчики с typeObj=1 — нет, так не работает. Я такой: ладно, Redis минус, берём SQLite.

Нахожу RediSearch

Продолжаю копать и нахожу модуль — RediSearch. Устанавливаю, настраиваю индексы:

FT.CREATE idx:cur ON HASH PREFIX 1 cur:
  SCHEMA typeObj NUMERIC objId NUMERIC parId NUMERIC

Теперь поиск по нескольким полям работает:

FT.SEARCH idx:cur "@typeObj:[1 1] @objId:[100 100]" LIMIT 0 1000

Оч круто. Есть поиск, есть скорость. Начинаю тестировать производительность с индексами.

Скорость записи RediSearch — 150 000–170 000 вставок/сек.

Упала в 4 раза по сравнению с чистым Redis. Индексы дорого стоят.

Смотрю на SQLite — 370 000 на диске, 700 000 in-memory. Выглядит выгоднее. Начинаю склоняться к SQLite.

Тестирую многопоточность — и всё ломается

Запускаю 100 потоков. Смотрю в логи.

org.sqlite.SQLiteException: [SQLITE_BUSY]
The database file is locked (database is locked)

Не один раз. Каждые несколько секунд.

Скорость падает с 370 000 до 98 000 вставок/сек — в почти 4 раза. А данные при этом теряются.

Почему SQLite теряет данные на многопоточке

SQLite работает с блокировкой на уровне файла. Даже в WAL-режиме — только один писатель в каждый момент. Остальные потоки ждут или получают SQLITE_BUSY и пропускают запись.

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

Race Condition — это когда два потока одновременно пытаются изменить одни данные, и результат зависит от того, кто успеет первым. У SQLite в многопоточной записи именно это и происходит.

Можно настроить PRAGMA busy_timeout, выстроить очередь — но это уже костыли. Инструмент не для этого.

SQLite in-memory ещё хуже: каждое соединение получает изолированную базу, при рестарте все данные исчезают, при многопоточной записи теряется до 10% данных без специальной оптимизации.

Почему RediSearch выигрывает несмотря на меньшую скорость

Redis обрабатывает команды в одном потоке. Звучит как ограничение — на деле это гарантия: никаких блокировок, никакого Race Condition.

При росте числа потоков RediSearch не падает. Результаты даже слегка улучшаются — очередь команд выстраивается эффективнее. Никаких SQLITE_BUSY. Данные не теряются.

Redis как очень быстрый и организованный кладовщик — он один, но обрабатывает заказы строго по очереди и никогда не путает. Именно поэтому параллельные клиенты не мешают друг другу.

Важно знать: FT.SEARCH по умолчанию возвращает не больше 10 000 записей. Нужна пагинация через LIMIT offset count. JOIN между разными индексами нет — придётся делать два запроса и связывать на стороне приложения. Стандартный паттерн для NoSQL, просто держите в голове.

Цифры нагрузочного тестирования

Инструмент

Запись зап./сек

Многопоточность

SQLite (диск, WAL, кэш 400 МБ)

~370 000

При 100 потоках падает до ~98 000; SQLITE_BUSY в логах

SQLite (in-memory)

~700 000

Теряет до 10% данных без оптимизации

Redis (чистый HSET, без индексов)

~650 000

Нет проблем — однопоточный обработчик

RediSearch (с индексами)

~150 000–170 000

Нет проблем; при росте потоков результат улучшается

Таблица рисков

Риск

SQLite

RediSearch

Многопоточная запись

Единственный писатель; SQLITE_BUSY; потери данных

Нет блокировок; предсказуемая скорость

Объём данных

Неограничен (диск); деградация после 50–100 ГБ

Ограничен RAM; индексы занимают в 2–5 раз больше данных

Потеря данных при сбое

Полный ACID; WAL защищает

Без AOF/репликации — потеря последних операций

Поиск и JOIN

Полный SQL + JOIN

Нет JOIN; нужно два запроса + связка в коде

Масштабирование

Вертикально, один файл

Redis Cluster, горизонтально

Eviction

При переполнении памяти удаляет старые ключи по LRU

Итог

SQLite хорош. Для одного-двух потоков, небольших объёмов, простой аналитики — отличный выбор. Как только появляется конкурентная запись от сотни потоков — начинаются проблемы.

RediSearch медленнее на бумаге: 150 000 против 700 000. Но это предсказуемые 150 000 без потерь на любом числе потоков. Против непредсказуемого SQLite, который теряет данные и падает до 98 000 под нагрузкой.

Для высоконагруженной системы с множеством параллельных источников — RediSearch надёжнее. Даже с более низкой пиковой скоростью.

Если интересно следить за процессом — канал @java_quant

Пообщаться или задать вопрос — @karim_product, на связи.