Вопрос о производительности Memcached / Microsoft Velocity

Просто случайный запрос по Microsoft Velocity.

Сценарий: Допустим, мне нужны ВСЕ заказы из моей базы данных. В SQL это нормально, я умею SELECT OrderId,TotalCost... from Orders. Это один путь к моей базе данных туда и обратно, и все довольны.

Теперь, если я использую Memcached или (как я использую сейчас) Microsoft Velocity (CTP3), нет простого способа сделать это. Я вижу два варианта (в псевдокоде)

FOR EACH ORDER
     Order = cache.TryGet(OrderId)
     if Order is null
            Order = db.Get(OrderId)
END FOR EACH

что было бы НАГРУЗКА туда и обратно.

Также считайте, что я хочу получать заказы от Клиента.

SQL: Select OrderId....TotalCost from Orders where CustomerId = MyCustomerId

Одна поездка туда и обратно, все довольны.

Используя кешированное решение, я действительно вижу два решения:

Решение 1:

DOES CustomerOrderIdsForCustomerId EXIST
     NO
           POPULATE CustomerOrderIdsForCustomerId FROM DATABASE
     YES
           FOR EACH OrderId IN CustomerOrdersForCustomerId
                  cache.TryGet(OrderId)
                  IF Order IS NULL
                        Order = db.Get(OrderId)
           END FOR EACH

Решение 2 - хранить сериализованный список всех заказов клиентов в собственном объекте кеша. Уменьшает количество поездок туда и обратно, но просто кажется отстойным.

Кто-нибудь может пролить свет на эту ситуацию?


person sjhuk    schedule 19.11.2009    source источник


Ответы (2)


Тот факт, что у вас есть кеш, не означает, что вы должны использовать его для каждого запроса! В этом случае, как вы уже определили, это вам не очень помогает, и я, вероятно, сразу перейду к базе данных для такого рода вещей.
Однако это немного зависит от вашего приложения - если вы думаете, что клиенты регулярно собираетесь просматривать их историю заказов, или у вас есть функция, которая анализирует заказы, чтобы узнать, какие продукты популярны, тогда вы можете использовать некоторое кеширование, чтобы снизить нагрузку на свой SQL-сервер. В этом случае я бы, вероятно, оставил в кеше либо DataTable с заказами, либо коллекцию заказов и запросил бы его с помощью LINQ, чтобы показать заказы для клиента.

person PhilPursglove    schedule 23.11.2009
comment
Я согласен с тем, что не следует всегда использовать кеш. Однако я бы сказал, что, скажем, у меня есть коллекция заказов (или даже храню все заказы в их собственном регионе), чтобы вернуть все заказы с использованием синтаксиса LINQ, я бы сделал: var x = from Orders in dc.GetOrdersInRegion (Заказы) выберите Orders.Value; а затем перебирать их таким образом. Если мне нужны заказы для определенного клиента, я бы сделал var x = from Orders в dc.GetOrdersInRegion (Orders), где ((Order) Orders.Value) .CustomerId == customerGuid select Orders.Value; Оба будут иметь одинаковый сетевой трафик, хотя - person sjhuk; 25.11.2009
comment
+1. Запрашивать ВСЕ строки через какой-то энергозависимый кеш памяти просто не имеет смысла. - person filiprem; 22.12.2009

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

Вариант 1. Используйте регионы

Вы можете создать регион и получить все объекты из этого региона одним вызовом. В вашем сценарии вы можете создать регион Orders, в котором вы можете хранить все заказы, а затем использовать GetObjectsInRegion, чтобы получить все заказы в кеше. Однако обратите внимание, что это возвращает все заказы в кеше ... которые могут иметь или не иметь все заказы, которые у вас есть в базе данных.

Вариант 2. Используйте регионы и теги

Velocity позволяет помечать объекты, которые вы помещаете в области кэша, а затем извлекать их с помощью этих тегов. Итак, в вашем сценарии вы можете пометить объекты заказа тегом «order», а затем использовать GetObjectsByTag для их получения. Поскольку вы можете использовать несколько тегов, вы также можете пометить их тегом идентификатора клиента, а затем вытащить их таким образом.

Эти 2 варианта сопровождаются некоторыми оговорками, поэтому обязательно ознакомьтесь с документацией: Методы на основе тегов скорости

person jvilalta    schedule 19.11.2009