Как правило, приложения обрабатывают операции бизнес-логики, отправляя код для выполнения в базу данных. Это медленный процесс, поскольку код передается от клиента на сервер каждый раз, когда выполняется функция. Код, который используется для работы с одной и той же базой данных, может повторятся в разных приложениях, соответственно разработчик несет ответственность за поддержание согласованности этого кода в независимости от того, выполняет ли код простые запросы или сложные операции с данными. Следуя манифесту Redis «Мы против сложности», нам пришлось принять меры и найти решение этих проблем. Четыре года назад мы представили RedisGears, нашу первую модель программирования на платформе. Разработчики писали и выполняли скрипты в непосредственной близости от данных. Однако скрипты были эфемерными и предоставлялись каждым клиентом по отдельности, что могло привести к неконсистентности. Следуя этому направлению, в Redis 7.0 мы представили первоначальную реализацию поддержки скриптов с функциями . Функции повысили удобство использования и надежность, поскольку они являются частью базы данных и в их отношении работает  репликация и надежная запись на диск. И теперь мы с гордостью представляем следующий шаг. В Redis 7.2 мы представили триггеры и функции . Они улучшают программируемость Redis, расширяют возможности серверной части, улучшают способ и время выполнения функций в базе данных и облегчают выполнение сложной бизнес-логики непосредственно там, где находятся данные. Триггеры и функции — это новое поколение возможностей программирования, доступное через Redis Stack. Они позволяет разработчикам программировать, хранить и автоматически выполнять код JavaScript при изменении данных непосредственно в базе данных Redis. Эта возможность позволяет разработчикам определять события (триггеры) для выполнения функций в непосредственной близости с данными. То есть разработчики определяют бизнес-логику, которая выполняется в ответ на события или команды базы данных. Это ускоряет код и взаимодействие, поскольку не нужно ждать, пока код от клиентов будет перенесен в базу данных. Это также ускоряет время реакции на другие события в Redis, такие как уведомления пространства ключей (keyspace notifications), которые не обрабатываются в реальном времени другими средствами, такими как события публикации и подписки (Pub/Sub). Так же триггеры и функции контролируют распределение внутри кластерной базы данных, устанавливая библиотеки на каждый сегмент и выполняя функции в зависимости от того, где находится ключ. Мы также ввели удаленные функции (remote functions). Удаленные функции позволяют выполнять чтения на любом слоте, даже в кластерной базе данных, поэтому все ваши данные доступны из каждой функции. Redis использует Lua для сценариев и функций. У Lua есть много преимуществ , таких как возможность повторного использования кода, но он не является широко используемым языком среди профессиональных разработчиков. Согласно опросу разработчиков StackOverflow 2022 года , только 3,2% разработчиков используют Lua профессионально. Напротив, две трети разработчиков используют JavaScript. Использование известного языка снижает барьер входа для новых разработчиков Redis. Не нужно учить еще один язык. Еще одним преимуществом триггеров и функций является то, что они уменьшают сложность управления бизнес-логикой в нескольких приложениях одновременно. Когда несколько приложений обращаются к одной и той же базе данных, разработчикам приходится координировать, как приложения последовательно обрабатывают данные. Обычно код дублируется в каждом приложении для валидации данных, улучшения результатов поиска или обновления базы данных, когда другое приложение вносит изменения. Благодаря триггерам и функциям больше нет необходимости дублировать код в нескольких приложениях. Код всегда выполняется одинаково: после ручного вызова или в качестве реакции на событие в базе данных. До сих пор реакция на события базы данных в Redis требовала от разработчиков использования механизма Pub/Sub. Хотя Pub/Sub имеет множество преимуществ, это не всегда правильный выбор. В частности, Pub/Sub не работает в режиме реального времени. Клиент должен иметь активную подписку на события; если клиент не слушает, события теряются. Теперь разработчики могут регистрировать триггеры пространства ключей, которые выполняются на основе префикса ключа и типа события. Триггер выполняется атомарным образом, соответственно стороннее событие не будет обработано между оригинальным событием и вашей бизнес-логикой. Всегда легче понять ситуацию на практическом примере. Здесь мы представляем регистрацию функции и триггера. Функция выполняется, когда она вызывается с помощью команды TFCALL; триггер выполняется на основе событий в Redis. В прологе указано, что мы используем движок js, имя библиотеки — lib, а минимально необходимый API триггеров и функций — версия 1.0. Далее мы создаем функцию, которая возвращает результат команды Redis. Аргумент client предоставляет доступ для выполнения команд. А аргумент data содержит ключи и другие аргументы, с которыми может быть вызвана функция. Глобальная переменная redis позволяет регистрировать триггеры и функции, а также логгировать что-либо. При регистрации мы назначаем функции имя, с которым сможем ее вызвать впоследствии: Полый JavaScript файл выглядит следующим образом (сохраним его как lib.js): Затем мы загружаем нашу функцию в Redis с помощью команды TFUNCTION LOAD (это так же распространяет написанную библиотеку по всему кластеру). Теперь мы можем вызвать функцию с помощью команды TFCALL. Полное имя функции состоит из имени библиотеки и имени функции через точку: Тем самым мы успешно создали, зарегистрировали и запустили функцию в базе данных Redis. Мы можем расширить этот пример с помощью триггера пространства ключей. Мы добавляем триггер, который реагирует на ключи с префиксом fellowship:. Добавьте этот код в конец файла lib.js: Для обновления существующей библиотеки нужно воспользоваться командой TFUNCTION LOAD с аргументом REPLACE. После выполнения обновленная версия библиотеки станет доступна всем клиентам Redis, и они начнут использовать новую бизнес-логику: Чтобы протестировать новый триггер пространства ключей, создайте новый ключ, начиная с felowship: и проверьте поля с помощью RedisInsight. Триггер пространства ключей выполняется непосредственно во время добавления новой записи, поэтому поле last_updated уже присутствует сразу после создания ключа. Присоединяйтесь к общедоступной предварительной версии триггеров и функций с помощью Redis Stack 7.2. Можно начать работать с Redis Stack в облаке, создав базу данных Redis Enterprise Cloud с использованием fixed tier в Google Cloud/Asia Pacific (Tokyo) или AWS/Asia Pacific (Singapore) или разверните экземпляр самостоятельно с помощью центра загрузки. Стабильная версия триггеров и функций запланирована на релиз Redis 8. Она будет включать в себя фидбек, полученный от пользователей предварительной версии, а также дополнительные функции, такие как временные триггеры и дополнительные возможности по отладке. Комментарии и отзывы приветствуются в списке рассылки Redis. От переводчика. В оригинальной статье некоторые технические моменты опущены, без которых создается ощущение недосказанности. Давайте восполним: Официальная документация - тут. Под капотом JavaScript в Redis использует всеми известный V8 (читайте в релизе RedisGears от 20 июня). Версия v8 свеженькая 11+, так что все прелести современного js доступны. Команда Redis старается продвигать облачные Redis Stack и Redis Enterprise всеми силами, но это необязательно. Проще всего попробовать с помощью докер docker run -it --rm redis/redis-stack-server:7.2.0-v2. Или упражняться с установкой RedisGears последней версии с поддержкой JavaScript на голый Redis. Последний докер от RedisGears у меня на Mac работать не хочет (видимо сказывает тот факт, что нет билда под arm64). В любое случае ссылочки по RedisGears тут: докер redislabs/redisgears и сборка из исходников (кстати, написан на Rust). Программировать либы на JS под Redis можно не только для себя любимого, а в опенсорс (проигрыш по с скорости с сишными модулями оставим за скобками). Здесь встает вопрос конфигурирования такого модуля и у команды Redis уже есть готовый ответ на это - Triggers and functions / Concepts / Library configuration. Спасибо за внимание! Веду канал Alex Code в телеграме про разработку и не только ;-)  CTO TIMELESS