Подтвердить что ты не робот

Когда использовать хранилище ключей для веб-разработки?

Когда кто-то будет использовать хранилище ключей (Redis, memcache и т.д.) Для веб-разработки? Фактический вариант использования был бы наиболее полезным.

Я путаюсь с тем, что простая база данных кажется гораздо более функциональной, потому что, насколько я понимаю, она может делать все, что может делать хранилище значений ключей, плюс она также позволяет выполнять фильтрацию/запросы. Это означает, что, насколько я понимаю, вы НЕ МОЖЕТЕ делать фильтр как:

select * homes where price > 100000

с хранилищем ключ-значение.

Пример

Давайте представим, что Qaru использует хранилище значений ключей (memcache, redis и т.д.).

Как хранилище ключей может помочь в удовлетворении потребностей хостинга Stackoverflow?

4b9b3361

Ответ 1

Я не могу ответить на вопрос о том, когда использовать хранилище данных с ключом (здесь kv), но я могу показать вам некоторые примеры и ответить на ваш пример stackoverflow.

С доступом к базе данных, большая часть того, что вам нужно, это kv-магазин. Например, пользователь входит в систему с именем пользователя "joe". Таким образом, вы просматриваете "user: joe" в своей базе данных и получаете его пароль (хэш конечно). Или, может быть, у вас есть пароль под "user: pass: joe", это действительно неважно. Если это было переполнение стека, и вы отображали страницу http://stackoverflow.com/questions/6935566/when-to-use-a-key-value-store-for-web-development, вы бы искали "вопрос: 6935566" и использовали это. Легко видеть, как магазины kv могут решить большинство ваших проблем.

Я хотел бы сказать, что kv-хранилище является подмножеством функциональности, предоставляемой традиционной RDMS. Это связано с тем, что дизайн традиционной RDMS обеспечивает множество проблем масштабирования и, как правило, теряет функции по мере масштабирования. В магазинах kv нет таких функций, поэтому они не ограничивают вас. Однако эти функции часто могут создаваться в любом случае, сконструированные из ядра для масштабируемости (потому что это становится сразу же очевидным, если они не являются).

Однако это не означает, что есть вещи, которые вы не можете сделать. Например, вы указываете запрос. Это ловушка многих магазинов kv, поскольку они, как правило, агностик ценности (не всегда истинный, например, redis и т.д.) И не имеют возможности найти то, что вы ищете. Хуже того, они не предназначены для этого быстро, они просто очень быстро ищут ключ.

Одним из решений этой проблемы является сортировка ваших ключей лексикографически и разрешение запросов диапазона. Это по существу "дайте мне все между вопросом: 1 и вопрос: 5". Теперь этот пример довольно бесполезен, но есть много применений запросов диапазона.

Вы сказали, что хотите, чтобы все дома составляли более 100 000 долларов. Если вы хотите, чтобы это было сделано, вы бы создали индекс домов по цене. Скажем, у вас были следующие дома.

house:0 -> {"color":"blue","sold":false,"city":"Stackoverville","price":500000}
house:1 -> {"color":"red","sold":true,"city":"Toronto","price":150000}
house:2 -> {"color":"beige","sold":false,"city":"Toronto","price":40000}
house:3 -> {"color":"blue","sold":false,"city":"The Blogosphere","price":110000}

В SQL вы будете хранить каждое поле в столбце, а затем все это в одном (в данном случае JSON) документе. И мог SELECT * FROM houses WHERE price > 100000. Кажется, все прекрасно и денди, но если индекс не построен, это требует взглянуть на каждый дом в вашем столе и проверить его цену, которая, если у вас есть несколько миллионов домов, может быть медленной. Итак, с магазином kv вам нужен индекс. Основное различие заключается в том, что база данных SQL молча выполняла бы медленную вещь, где хранилище kv не было бы.

Если у вас нет запросов на диапазон, вам нужно будет привязать свой индекс в одном документе, что значительно облегчит его обновление, а значит, вам нужно будет загрузить весь индекс для каждого запроса, опять же, ограничивая масштабируемость.

house:index:price -> [{"price":500000,"id":"0"},{"price":150000,"id":"1"},{"price":110000,"id":"3"},{"price":40000,"id":"2"}]

Но если у вас есть запросы диапазона (часто называемые ключевыми словами), вы можете создать такой индекс:

house:index:price:040000 -> 2
house:index:price:110000 -> 3
house:index:price:150000 -> 1
house:index:price:500000 -> 0

И затем вы можете запросить ключи между house:index:price:100000 и house:index:price:: (символ ":" - символ после "9" ), и вы получите [3,1,0], который является всеми домами, более дорогими, чем 100 000 долларов США ( они также помогают в порядке). Еще одна приятная вещь в этом заключается в том, что они, вероятно, будут на одном "разделе" вашего кластера, поэтому этот запрос займет примерно столько же времени, что и "singe get" (плюс крошечные дополнительные накладные расходы), или два получат, если ваш диапазон будет переходить граница сервера (но это можно сделать параллельно!).

Итак, это показывает, как делать запросы в хранилище kv. Вы можете запросить все, что можно заказать в виде строки (что угодно), и быстро просмотреть ее. Если у вас нет запросов на диапазон, вам нужно будет хранить весь ваш индекс под одним ключом, который отстой, но если у вас есть запросы к диапазону, это очень хорошо и очень быстро. Вот более сложный пример.

Я хочу, чтобы непроданные дома в Торонто составляли менее 100 000 долларов. Мне просто нужно разработать свой индекс. (Я добавил в несколько домов, чтобы сделать его более значимым). Сначала подумал, что вы можете просто создать еще один индекс для каждого свойства, но вы быстро поймете, что это означает, что вам нужно выбрать каждый непроданный дом и загрузить его из базы данных. (Это то, что я имел в виду, когда я сказал, что проблемы масштабирования сразу же очевидны.) Решение заключается в использовании мультииндекса. После создания вы можете выбрать именно нужные значения.

house:index:sold:city:price:f~Fooville~000010:5        -> ""
house:index:sold:city:price:f~Toronto~040000:2         -> ""
house:index:sold:city:price:f~Toronto~140000:4         -> ""
house:index:sold:city:price:t~Stackoverville~500000:0  -> ""
house:index:sold:city:price:t~The Blogosphere~110000:3 -> ""
house:index:sold:city:price:t~Toronto~150000:1         -> ""

Теперь, в отличие от последнего примера, я помещаю идентификатор в ключ. Это позволяет двум домам иметь одинаковые свойства. Я мог бы объединить их в значение, но добавление удаляющих индексов становится более сложным. Я также решил отделить мои данные с помощью ~. Это потому, что оно лексикографически после всех букв, гарантируя, что полное имя будет отсортировано, и мне не нужно вставлять каждый город в ту же длину. В производственной системе я бы, вероятно, использовал байты 255 или 0.

Теперь диапазон house:index:sold:city:price:f~Toronto~100000 - house:index:sold:city:price:f~Toronto~~ выберет все дома, соответствующие запросу. И важно отметить, что запрос масштабируется линейно с количеством результатов. Это означает, что вам нужно создать индекс для каждого набора свойств, который вы хотите индексировать (хотя индекс в нашем примере также работает для проданных и проданных запросов). Это может показаться большой работой, но, в конце концов, вы понимаете, что именно это вы делаете, а не в своей базе данных. Я уверен, что мы скоро увидим библиотеки для такого рода вещей: D

После растягивания темы немного, я показал:

  • Некоторые использования хранилища kv.
  • Как выполнять запросы в хранилище kv.

Я думаю, что вы обнаружите, что kv-магазины достаточно для многих приложений и часто обеспечивают лучшую производительность и доступность, чем традиционные RDMS. При этом каждое приложение отличается и поэтому невозможно ответить на исходный вопрос.

Ответ 2

Не путайте базу данных типа NoSQL с чем-то вроде memcached (который не предназначен для постоянного хранения данных).

Типичное использование memcached - хранить некоторые результаты запроса, к которым может обращаться кластер веб-серверов, т.е. общий кэш. Например. На этой странице приведен список связанных постов, и для создания базы данных, вероятно, потребуется немного работы для создания этого списка. Если вы делаете это каждый раз, когда кто-то загружает страницу, вы создадите большую работу для базы данных. Вместо этого результаты, однажды полученные в первый раз, могут быть сохранены на сервере memcached с ключом, являющимся идентификатором страницы. Любой из веб-серверов в кластере может получить эту информацию очень быстро, без постоянного попадания в базу данных. Через некоторое время запись в кеш будет очищена memcached, чтобы результаты для старых статей не занимали места. [Отказ от ответственности: я понятия не имею, если StackOverflow делает это на самом деле].

База данных "NoSQL", с другой стороны, предназначена для постоянного хранения информации. Если ваша схема данных довольно проста и ваши запросы, то она может быть быстрее, чем стандартная база данных SQL. Многим веб-приложениям не нужны чрезвычайно сложные базы данных, поэтому базы данных NoSQL могут быть в хорошей форме.

Ответ 3

Существует два общих варианта использования noSQL:

  • Быстрая разработка приложений
  • Массивно масштабируемые системы

Тот факт, что большинство решений noSQL эффективно не имеют схемы; требуют гораздо меньше церемоний для работы; являются легкими (с точки зрения API); и обеспечивают значительный прирост производительности, в отличие от более канонических реляционных систем сохранения, сообщают о своей пригодности для вышеуказанных 2 случаев использования (в общем смысле).

Будучи циничным - или, возможно, практичным в бизнес-смысле, можно предложить третий общий прецедент для систем noSQL (все еще сообщается вышеуказанным набором характеристик/функций):

Легче заразиться, и любой неопытный (но не умственный мозг) аспирант может забрать его. Это очень мощная функция. (Попробуйте это с Oracle..)

Таким образом, варианты использования систем noSQL, которые в целом можно охарактеризовать как расслабленные постоянные системы, оптимально информированы практическими соображениями.

Нет абсолютно никакого вопроса - за пределами огромно масштабируемых систем - что системы РСУБД являются формально совершенными системами, предназначенными для обеспечения целостности данных.

Ответ 4

Хранилища с ключевыми значениями обычно бывают очень быстрыми, поэтому полезно иметь их в качестве кеша для данных, которые сильно доступны и редко обновляются, чтобы уменьшить нагрузку на ваши БД.

Как вы сказали, вы, как правило, ограничены запросами (хотя MongoDB обрабатывает их довольно хорошо), но хранилища с ключевыми значениями в основном предназначенный для доступа к точным данным: профиль пользователя X, информация о сеансе X и т.д.

"Традиционная" БД, вероятно, будет более чем достаточно для среднего веб-сайта, но если вы испытываете большие нагрузки, то хранилища с ключевыми значениями могут действительно помочь вашему времени загрузки.

EDIT: И под "высокими нагрузками" я имею в виду действительно высокие нагрузки. Хранилища с ключевыми значениями редко необходимы.

См. это сравнение хранилищ для ключей.

Ответ 5

Просто добавив ответ bstrawson, "mem- кеш -d" - это механизм кэширования, в то время как Redis является постоянным хранилищем, но оба сохраняют данные в виде пары ключ-значение.

Поиск в хранилище с ключом (что-то вроде Redis или Membase) больше похож на поиск всего значения в реляционной базе данных, слишком медленный. Если вы хотите выполнить некоторые запросы, вам может потребоваться перейти к документированному DB типа типа NoSQL, таким как MongoDB или CouchDB, которые вы можете выполнить часть запроса.

В ближайшем будущем вы сможете обрабатывать couchbase sever 2.0, который будет решать все ваши проблемы с записью с помощью запроса данных NoSQL с недавно введенным UnQL и кеширование (непосредственно полученное из исходного кода memcached)

Ответ 6

Переполнение стека действительно использует Redis и широко. Подробный ответ на ваш вопрос с помощью Qaru в качестве примера в несколько приятных сообщения в блоге от @Mark Gravell. Марк является автором полностью Booksleeve полностью-асинхронной библиотеки привязки .NET Redis.