Те, кто включил в своём приложении на GAE поддержку сессий, знают, что сессии, во-первых, записываются в datastore, а во-вторых, автоматически оттуда не исчезают. От протухших сессий надо как-то избавляться самостоятельно.
Я как-то не заботился о протухших сессиях, и за полтора года их накопилось полтора миллиона штук. Недавно размер хранимых в datastore данных превысил бесплатную квоту и, так как 99% было занято сессиями, я решил поудалять протухшие.
Разумеется, грешно было не воспользоваться для этой цели недавно выпущенным Mapper API. Накорябал простенький Mapper. Для начала решил просто посчитать, без удаления:
И запустил. Шестерёнки завертелись, GAE в четыре руки стал ворошить мои сессии. Через несколько часов я обнаружил, что сайт лежит, превышение квоты. Заглянул в консоль и увидел, что исчерпана CPU квота (8.5 CPU-часов). Удивился. Повысил квоту и на следующий день запустил mapreduce ещё раз, теперь уже раскомментировав строки, удаляющие сущности.
Ура. Всего за 2.5 часа абсолютного времени облачные мегатехнологии справились с задачей, сожрав в итоге 22 CPU-часа.
Задумался. Что-то не так в облаках. Я не пробовал, но почему-то думаю, что даже MySQL справится с
за несколько минут. Даже с миллионом строк и даже с двумя миллионами. Но это же так старомодно, всё на одной машине, без масштабируемости и избыточности, и всё такое…
Update: Чтоб удалить из datastore сессии необязательно писать mapreduce, можно и волшебный сервлет дёрнуть и вручную курсором итерировать. Но для того чтоб посчитать, сколько их протухло в каждый день (что-то типа SELECT COUNT(*) FROM _ah_SESSION GROUP BY _expires /( 86400*1000 )) сервлет никто не написал, и скорее всего придётся таки гонять mapreduce, с примерно тем же проигрышем примитивной СУБД.
Я как-то не заботился о протухших сессиях, и за полтора года их накопилось полтора миллиона штук. Недавно размер хранимых в datastore данных превысил бесплатную квоту и, так как 99% было занято сессиями, я решил поудалять протухшие.
Разумеется, грешно было не воспользоваться для этой цели недавно выпущенным Mapper API. Накорябал простенький Mapper. Для начала решил просто посчитать, без удаления:
public class SessionCleanupMapper
extends AppEngineMapper<Key, Entity, NullWritable, NullWritable> {
@Override
public void map(Key key, Entity value, Context context) {
Object expiresProperty = value.getProperty("_expires");
if (expiresProperty instanceof Long) {
long expiresTimestamp = ((Long)expiresProperty).longValue();
if (expiresTimestamp < System.currentTimeMillis()) {
context.getCounter("Session", "expired").increment(1);
// DatastoreMutationPool mutationPool = this.getAppEngineContext(context).getMutationPool();
// mutationPool.delete(value.getKey());
}
}
}
}
И запустил. Шестерёнки завертелись, GAE в четыре руки стал ворошить мои сессии. Через несколько часов я обнаружил, что сайт лежит, превышение квоты. Заглянул в консоль и увидел, что исчерпана CPU квота (8.5 CPU-часов). Удивился. Повысил квоту и на следующий день запустил mapreduce ещё раз, теперь уже раскомментировав строки, удаляющие сущности.
Ура. Всего за 2.5 часа абсолютного времени облачные мегатехнологии справились с задачей, сожрав в итоге 22 CPU-часа.
Задумался. Что-то не так в облаках. Я не пробовал, но почему-то думаю, что даже MySQL справится с
DELETE FROM _ah_SESSION WHERE _expires < NOW()
за несколько минут. Даже с миллионом строк и даже с двумя миллионами. Но это же так старомодно, всё на одной машине, без масштабируемости и избыточности, и всё такое…
Update: Чтоб удалить из datastore сессии необязательно писать mapreduce, можно и волшебный сервлет дёрнуть и вручную курсором итерировать. Но для того чтоб посчитать, сколько их протухло в каждый день (что-то типа SELECT COUNT(*) FROM _ah_SESSION GROUP BY _expires /( 86400*1000 )) сервлет никто не написал, и скорее всего придётся таки гонять mapreduce, с примерно тем же проигрышем примитивной СУБД.