1) можно просто по крону выполнять в консольную команду типа cut access.log -d' ' -f 7 | sort | uniq -c и сбрасывать результат в базу.
2) мемкеш не будет удобен, рано или поздно он начнёт сам удалять счётки, по тайм ауту или по нехватке памяти и это надо иметь ввиду, соответственно и решение должно быть рассчитано на потери. Т.е. например если в мемкеш ключ пуст, то забираем значение из базы и кладём в него, для отображения тоже используем значение из мемкеша, при запросе страницы инкрементируем ключ в мемкеш. А вот значение в базе обновляем например из методом описным в первом пункте. Соответственно играясь с временем жизни записей в мемкеше и частотой парсинга логов будем регулировать возможные лаги в значениях счётчика.
3) парсинг логов можно заменить на очереди типа rabbitmq
4) в большинстве случаев можете не париться и вынести счётчики в
redis.io