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

Чего стоит почистить 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, с примерно тем же проигрышем примитивной СУБД.
Теги:
Хабы:
+47
Комментарии 27
Комментарии Комментарии 27

Публикации

Истории

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

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн