Построение индексов
Redis
Петр Трофимов, onliner.by
Товар в каталоге
Скомпилировать seo-заголовок товара
Seo, keywords, description
Посчитать обсуждения на форуме
Узнать рейтинг и кол-во отзывов
Скомпилировать краткую строку
Узнать диапазон цен магазинов
Проверить б/у предложения
Загрузить конфигурации
Загрузить галерею, видео, 3d-изображение
Получить группы параметров, сами параметры и их значения для товара
Как быстро отображать эту
информацию?
Покрыть кэшем
Нагрузка на сервер все равно остается
Пользователь видит неактуальную информацию
Держать кэш все время поднятым
Огромные интервалы между индексациями
Процессор все время занят
Event-based денормализация
Redis
Каталог B2B Баралог Корзина
Сервис
денормализации
DB
...
API
Булев параметр
NONE
YES
NO
Булев параметр
SET
1
2
5
SADD mobile:memory_cards:true 6
memory_cards=true
SMEMBERS mobile:memory_cards
1
5
2
6
Iphone6 (id = 6)
Собственно, содержание
Индексы и объекты
Индексация и поиск по параметрам
Булевы и flag-параметры
Словари и их диапазоны
Числа и их диапазоны
Карты отображения
Сочетание параметров
Сортировка
Числа и строки
Составная
Группировка
Как написать код
Индексы и объекты
Индексы
Объект
Объект
Объект
Поиск по
параметрам
Поиск по ID
Ссылки
Redis
Flag-параметры
ALL
YES
SADD mobile:onsale 6
onsale=true
SMEMBERS mobile:onsale 1
5
2
6
Iphone6 (id = 6)
SDIFF mobile:all mobile:onsale
Словари
SET
1
2
5
SADD mobile:mfr:apple 6
manufacturer=apple
SMEMBERS mobile:mfr:apple
1
5
2
6
Iphone6 (id = 6)
SINTERSTORE tmp mobile:mfr:apple mobile:mfr:samsung
SUNIONSTORE tmp mobile:mfr:apple mobile:mfr:samsung
SET
Словарный диапазон
SET
1
2
5
1
5
2
6
SUNIONSTORE tmp mobile:size:2 mobile:size:3 ...
Числа
ZADD mobile:price 600 6
Price = 600
5
6
Iphone6 (id = 6)
ZRANGEBYSCORE mobile:price 500 1000
3 => 300
4 => 400
5 => 500
ZRANGEBYSCORE + SADD = ZRANGEBYSCORESTORE (lua)
ZSET
Числовые диапазоны
-10 +20
Диапазон рабочих температур
start end
Overlap = start
Overlap = end
Overlap = complete
Overlap = inside
Overlap = partial
Карты отображения
Index Objects
1
2
100000
HASH
ID => KEY
6 => {catalog:product:iphone6}
Сортировка по числу
ZADD mobile:price 600 6
Price = 600
3
4
Iphone6 (id = 6)
ZRANGE mobile:price 1 2
ZCARD mobile:price
3 => 300
4 => 400
5 => 500
4
ZSET
Составная сортировка
3 => 300
4 => 400
5 => 500
3 => 0
4 => 0
5 => 1
price
is_new
ZUNIONSTORE tmp price is_new
WEIGHTS 1 1000
3 => 300
4 => 400
5 => 1500
composite
Сортировка по строке
Product:3 => Apple Iphone 3
Product:6 => Apple Iphone 6
3
4
5
SET
STRING KEYS
SORT set BY
Product:* ALPHA
STORE tmp
3
6
LIST
LRANGE list 1 5
Группировка
Object_id => parent_id
ZSET
ZINTER tmp set map
WEIGHTS 0 1
parent_id[]
Процесс индексации
1.трансформация объекта для индексации
2.построение цепочки index builder-ов
3.вычисление diff
4.выполнение index builder-ов
5.сохранение состояния индекса
6.коммит транзакции
7.событие - оповещение об изменении
индекса
Трансформация объекта для
индексации
{
"id": 598247,
"name": "Apple iPhone 6 (16Gb)",
"status": "active",
"rating": 3949,
"reviews_rating": 40,
"date": 1410278953,
"is_actual": true,
"has_no_parent": true,
"parent_id": null,
"manufacturer": "apple",
"key": "iphone6_16gb"
"parameters": {
"bool": {
"accelerometer": { "true": true },
...
},
"number": {
"acc_capacity": 181021,
"birthday": 1998,
...
},
"dictionary": {
"acc_type": { "nimh": true },
...
}
}
}
Построение цепочки index builder-
ов
$this->addBuilder(new IdIndex('id'))
->addBuilder(new IdMapIndex('key'))
->addBuilder(new StringOrderIndex('name'))
->addBuilder(new ArrayIndex('manufacturer'))
->addBuilder(new BoolIndex('is_actual'))
->addBuilder(new NumberIndex('rating'))
->addBuilder(new NumberIndex('date'))
->addBuilder(new NumberIndex('reviews_rating'))
->addBuilder(new BoolIndex('parameters.bool.*'))
->addBuilder(new BoolIndex('parameters.dictionary.*'))
->addBuilder(new NumberIndex('parameters.number.*'))
->addBuilder(new RangeIndex('parameters.range.*'))
->addBuilder(new ArrayIndex('parent_id'))
->addBuilder(new NumberIndex('group'));
Diff-механизм
Name: Apple Iphone 6
Price: 100000
Parameters:
Bool
Wifi: true
Number
Height: 100
Name: Apple Iphone 6
Price: 100000
parameters.bool.Wifi: true
parameters.number.Height: 100
Name: Apple Iphone 6
Price: 200000
parameters.bool.Wifi: true
Price: 200000
Parameters.number.height: 100
UPDATE
DELETE
Интерфейс index builder-а
/**
* This interface should be implemented by various Redis index builders
*/
interface BuilderInterface
{
/**
* Returns true if this key should be indexed by this builder
*/
public function matches($key);
/**
* Executes Redis command to update index
*/
public function update($redis, array $product, $key, $value);
/**
* Executes Redis command to delete index
*/
public function delete($redis, array $product, $key, $value);
}
Пример index builder-а
class BoolIndex extends Builder
{
public function matches($key)
{
return str_is($this->filter, $key);
}
public function update($redis, array $product, $key, $value)
{
if ($value) {
$redis->sadd($key, $product['id']);
}
}
public function delete($redis, array $product, $key, $value)
{
if ($value) {
$redis->srem($key, $product['id']);
}
}
}
Коммит транзакции
multi/pipeline
redis однопоточный
использование redis array
{catalog:product:1}:title
{catalog:product:1}:name
Методы обновления индекса
patchIndex
частичное обновление индекса
new = array_merge(previous, new)
putIndex
полная перезапись индекса
deleteIndex
удаление объекта из индекса
new = []
Процесс поиска
1.Создание цепочки Query на основе
аргументов
2.Выполнение подзапросов в рамках
IntersectionQuery в pipeline
3.Сортировка с пагинацией
4.Группировка (опционально)
5.Получение объектов по ID
6.Удаление временных ключей
Интерфейс Query
interface QueryInterface
{
/**
* Executes query to search products
*
* @param $redis
* @return string Redis key
*/
public function query($redis);
}
Пример Query
class ManufacturerQuery extends AbstractQuery implements QueryInterface
{
public function query($redis)
{
if (!is_array($this->value)) {
return $this->keys->indexKey("manufacturer:$this->value");
}
$unionKey = $this->keys->createKey('manufacturer');
$redis->sUnionStore(
$unionKey,
...$this->keys->mapIndexKeys("manufacturer:%s", $this->value)
);
return $unionKey;
}
}
Вопросы?
https://catalog.onliner.by
https://redis.io/documentation

More Related Content

PPTX
Redis and its Scaling and Obersvability
PDF
Node js (runtime environment + js library) platform
PPTX
하둡 고가용성(HA) 설정
PPTX
PROV-O Tutorial. DC-2013 Conference
PPTX
Rest api with node js and express
PDF
Advance Java Tutorial | J2EE, Java Servlets, JSP, JDBC | Java Certification T...
PDF
Introduction into ES6 JavaScript.
PPTX
ASP.NET Web Security
Redis and its Scaling and Obersvability
Node js (runtime environment + js library) platform
하둡 고가용성(HA) 설정
PROV-O Tutorial. DC-2013 Conference
Rest api with node js and express
Advance Java Tutorial | J2EE, Java Servlets, JSP, JDBC | Java Certification T...
Introduction into ES6 JavaScript.
ASP.NET Web Security

What's hot (20)

PPTX
[FOSS4G Korea 2016] Workshop - Advanced GeoServer
PDF
Intro to ggplot2 - Sheffield R Users Group, Feb 2015
PDF
Kubernetes on Premise Practical Guide
PDF
AWS 환경에서 MySQL BMT
PDF
PGConf.ASIA 2017 Logical Replication Internals (English)
PPTX
RDF Data Model
PDF
Microservices with Spring 5 Webflux - jProfessionals
PDF
Mastering RecyclerView Layouts
PDF
Tacker - a generic VNF Manager using OpenStack
ODP
Searching Relational Data with Elasticsearch
PPTX
TypeScript VS JavaScript.pptx
PDF
풀잎스쿨 - LIME 발표자료(설명가능한 인공지능 기획!)
PDF
Integrating React.js Into a PHP Application: Dutch PHP 2019
PDF
MSA 전략 1: 마이크로서비스, 어떻게 디자인 할 것인가?
PPTX
Introduction to Koltin for Android Part I
PDF
TypeScript Introduction
PPTX
PPTX
Neural Text Embeddings for Information Retrieval (WSDM 2017)
PPTX
Top 10 Cypher Tuning Tips & Tricks
[FOSS4G Korea 2016] Workshop - Advanced GeoServer
Intro to ggplot2 - Sheffield R Users Group, Feb 2015
Kubernetes on Premise Practical Guide
AWS 환경에서 MySQL BMT
PGConf.ASIA 2017 Logical Replication Internals (English)
RDF Data Model
Microservices with Spring 5 Webflux - jProfessionals
Mastering RecyclerView Layouts
Tacker - a generic VNF Manager using OpenStack
Searching Relational Data with Elasticsearch
TypeScript VS JavaScript.pptx
풀잎스쿨 - LIME 발표자료(설명가능한 인공지능 기획!)
Integrating React.js Into a PHP Application: Dutch PHP 2019
MSA 전략 1: 마이크로서비스, 어떻게 디자인 할 것인가?
Introduction to Koltin for Android Part I
TypeScript Introduction
Neural Text Embeddings for Information Retrieval (WSDM 2017)
Top 10 Cypher Tuning Tips & Tricks
Ad

Similar to Построение индексов Redis (20)

PDF
Андрей Богомолов Автоматизация дистрибуции информации о наличии и цене товара...
PDF
Поисковая оптимизация интернет-магазины на базе Drupal Commerce
PDF
Как создать дата-платформу с нуля / Павел Тарасов (ЦИАН)
PPTX
Эволюция к Behavior Driven Development на примере популярного фреймворка JBehave
PDF
Поисковая оптимизация интернет-магазина на базе Drupal Commerce
PDF
! реализовать настройки га 14 sergeev-etarget2011
PDF
! реализовать настройки га 14 sergeev-etarget2011
PDF
Виртуализация Данных: Введение
PPTX
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
PDF
Денис Паясь
PDF
Зачем интернет маркетологу понимать что такое API. Разбираем устройство API G...
PDF
OpenTalks.AI - Оптимизация бизнес-процессов и документооборота с использовани...
PDF
Jsfwdays 2013-2
PPTX
Эдгард Гомес - "Фишечки GTM"
PDF
Практическое применение MongoDB Aggregation Framework
PPS
Эдгард Гомез (Starcom Mediavest Group) - "Другая сторона Google Tag Manager"
PDF
Informatica for Data Warehouse Optimisation and Data Lake Use-cases
PDF
Mobile credentials
PPTX
Tag Management (рекламный контейнер)
PPTX
DUMP-2012 - Мобильные технологии - "Как мы выстраиваем разработку сервиса под...
Андрей Богомолов Автоматизация дистрибуции информации о наличии и цене товара...
Поисковая оптимизация интернет-магазины на базе Drupal Commerce
Как создать дата-платформу с нуля / Павел Тарасов (ЦИАН)
Эволюция к Behavior Driven Development на примере популярного фреймворка JBehave
Поисковая оптимизация интернет-магазина на базе Drupal Commerce
! реализовать настройки га 14 sergeev-etarget2011
! реализовать настройки га 14 sergeev-etarget2011
Виртуализация Данных: Введение
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
Денис Паясь
Зачем интернет маркетологу понимать что такое API. Разбираем устройство API G...
OpenTalks.AI - Оптимизация бизнес-процессов и документооборота с использовани...
Jsfwdays 2013-2
Эдгард Гомес - "Фишечки GTM"
Практическое применение MongoDB Aggregation Framework
Эдгард Гомез (Starcom Mediavest Group) - "Другая сторона Google Tag Manager"
Informatica for Data Warehouse Optimisation and Data Lake Use-cases
Mobile credentials
Tag Management (рекламный контейнер)
DUMP-2012 - Мобильные технологии - "Как мы выстраиваем разработку сервиса под...
Ad

Построение индексов Redis

Editor's Notes

  • #2: Key-value, memcache, catalog, show, lots info How many 17 gb - catalog, 700 k product, 700k categories Пример - каталог, с чего вдруг стали использовать редис. Показать на шапке товара
  • #6: Да нет фильтры, фильтрует список товаров, храним да и нет, отсутствие не храним
  • #7: Пример товара, готовая структура в редисе, пример добавления, пример поиска, готовый ключ, а чего вы не сделаете каталог на редис?. Пагинация, сортировка - позже
  • #10: Отличие от буль, есть множество всех, вычитание
  • #11: Теже флаги, отличия в ключе, плюс юнионы/диффы
  • #13: От до равно, inf для открытых,
  • #14: Отдельно для start/end, два множества
  • #15: Числовой айди, строковый ключ, хэш, схема ключа
  • #16: временный ключ при необходимости выполнение zinter сортированное/несортированное множество выполнение zrange/zrevrange для пагинации вычисление start/stop на основе page/limit выполнение zcard total found
  • #17: zunionstore weights
  • #18: индексация строк для сортировки используются строковые ключи (string) set/del приводится к нижнему регистру strtolower в имени ключа - ID объекта Method name? Hash? Product:titles : 123 -> apple iphone нельзя использовать zset, zrangebylex выполнение sort критерий сортировки - строковые ключи создание временного списка опция alpha = true опция store получение total count выполнение lrange пагинация
  • #19: индексация для группировки используются сортированные множества (zset) содержат карту отображения для группировки score - parent_id value - object_id Query after this ключ для группировки показывает связи между объектами выполняется обычный поиск попадают и обычные объекты, и представители групп выполняется zinter множество ID объектов сортированное множество базовый объект => дочерний объект weights 0, 1 выполняется zrange, array_unique, sadd из результата поиска отбираются сначала только базовые модели сортировка и пагинация затем - дочерние объекты формируется дерево объектов
  • #23: получаем текущее состояние индекса - hget приводим к плоскому виду текущее и новое состояние индекса - array_dot вызываем builder-ы для удаления и добавления - array_diff_assoc какие индексы существуют для объекта удалить объект из индексов при изменении характеристик быстрая переиндексация
  • #31: Sphinx vs redis slide after it