Как стать автором
Обновить

Чего стоит почистить datastore от сессий при помощи Mapper API

Время на прочтение2 мин
Количество просмотров1.2K
Те, кто включил в своём приложении на GAE поддержку сессий, знают, что сессии, во-первых, записываются в datastore, а во-вторых, автоматически оттуда не исчезают. От протухших сессий надо как-то избавляться самостоятельно.

Я как-то не заботился о протухших сессиях, и за полтора года их накопилось полтора миллиона штук. Недавно размер хранимых в 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, с примерно тем же проигрышем примитивной СУБД.
Теги:
Хабы:
Всего голосов 51: ↑49 и ↓2+47
Комментарии27

Публикации

Истории

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область