Кеш Yii2 не работает на высоких нагрузках, что делать?
1. Ваш кэш протухает за 20 секунд.
2. Возможно, для кэша выделено мало памяти, а json большой. Новые записи просто вытесняют старых из кэша.
Update:
3. Если следующий запрос приходит, когда первый еще не записался в кэш, тогда
3.1. если в кэше ничего нет, то сначала записать туда true. Потом сделать запрос, удалить из кэша (иначе результат не запишется!) и результат записать в кэш.
3.2. если в кэше json - отдать его
3.3. если в кэше true - sleep, проверить кэш еще раз. Но не более N раз. Если так и не дождался - идти дальше (сделать запрос и потом его записать в кэш).
Тоже столкнулся с проблемой параллельных запросов и на формирование данных при пустом кэше.
Рабочее решение: (только свои константы подставьте)static function getData($waiting_deep = 0)
    {
        //достаем $prts из кэша
        if (!(Yii::$app->cache->exists(self::CACHE_KEY__PRTS) AND is_array($prts = Yii::$app->cache->get(self::CACHE_KEY__PRTS)) AND isset($prts['version']) AND isset($prts['data']) AND is_array($prts['data']))) {
            // данных в кэше нет
            // выполняем процедуру подготовки данных с блокировкой для других процессов - чтобы другой процесс не начал делать тоже самое. В кэш поместить флаг блокировки Yii::$app->cache->set(CACHE_KEY__PRTS_FLAG_LOCK), а после подготовки данных и помещения их в кэш снять этот флаг блокировки. Если другой параллельный запрос не находит данных в кэше и при этом выставлен флаг блокировки Yii::$app->cache->exists(CACHE_KEY__PRTS_FLAG_LOCK), то он будет ожидать несколько(столькол сколько задана максимальная глубина ожидания) раз. Ограничиваем число ожиданий и интервал этих ожиданий.
            if (Yii::$app->cache->exists(self::CACHE_KEY__PRTS_FLAG_LOCK) AND Yii::$app->cache->get(self::CACHE_KEY__PRTS_FLAG_LOCK)) {
                if ($waiting_deep <= self::PRTS_FIND__WAITING_DEEP_MAX) {
                    usleep(self::PRTS_FIND__INTERVAL_WAITING_NEXT_CHECK_MICROSECONDS);
                    $prts = self::findPromoactionsRuleToShow($waiting_deep++);
                } else {
                    return false;
                }
            } else {
                Yii::$app->cache->set(self::CACHE_KEY__PRTS_FLAG_LOCK, true, 10); //сбросить флаг блокировки через 10 секунд в любом случае. Необходимо на случай ошибок при подготовки правил и следовательно невозможности в штатном режиме сбросить флаг блокировки.
                if (!($prts = self::prepareData())!==false){
					// кладем данные в кэш
					Yii::$app->cache->set(self::DATA_PRTS, $prts);
				}
				// Сбрасываем флаг блокировки
					// Yii::$app->cache->set(self::CACHE_KEY__PRTS_FLAG_LOCK, false);
				Yii::$app->cache->delete(self::CACHE_KEY__PRTS_FLAG_LOCK);
            }
        }
        return true;
    }