Posted on: February 07, 2022 11:53 PM
Posted by: Renato
Categories: Laravel PHP developer programming 100DaysOfCode
Views: 2255
Cache do Laravel
O cache é essencial para alcançar um alto desempenho e escalabilidade. A implementação da estratégia de cache adequada desde a fase de desenvolvimento é fundamental para evitar APIs atrasadas e tempos de carregamento de páginas lentos. Laravel é um dos frameworks PHP mais populares, portanto implementar a estratégia ideal de cache do Laravel é indispensável para uma melhor experiência do usuário e maior impacto nos negócios.
O que é cache do Laravel?
Laravel fornece uma implementação robusta e fácil de usar o cache e diferentes back-ends de cache. Com o cache Laravel, você pode alternar de forma eficiente e eficaz entre muitos mecanismos de cache sem escrever nenhum código.
Você pode encontrar a configuração do cache Laravel dentro da pasta config/cache.php
, embora você provavelmente só precisará do arquivo .env para alternar entre diferentes back-ends de cache.
O cache Laravel também fornece muitos métodos práticos que podemos usar para implementar diferentes estratégias de cache.
O cache é uma parte essencial do processo de desenvolvimento de software para quem se preocupa mais com o alto desempenho e a escalabilidade. 📈 Descubra tudo o que você precisa saber sobre o cache do Laravel aqui
Drivers de cache do Laravel e comparações
O cache Laravel fornece grandes back-end de cache e drivers. Dependendo do seu caso de uso, você pode alternar entre eles para melhorar o desempenho do seu aplicativo e o tempo de carregamento.
Dito isto, o cache Laravel também oferece uma forma perfeita de criar um back-end personalizado e usá-lo com o cache Laravel, mas apenas se a lista abaixo não se adequar ao seu caso de uso.
A seguir vamos falar sobre a lista de todos os back-ends fornecidos pelo cache do Laravel.
1. file
O driver file é o back-end padrão usado pelo cache do Laravel quando nenhum driver é especificado no arquivo .env.
O back-end do file é projetado para armazenar os dados em cache em um arquivo criptografado encontrado sob storage/framework/
. Laravel cria um arquivo criptografado com os dados e a chave de cache quando novos dados são armazenados em cache. O mesmo acontece quando o usuário está tentando recuperar o conteúdo. O cache Laravel pesquisa na pasta a chave especificada e, se encontrada, retorna o conteúdo.
Embora o back-end do file funcione sem falhas e poupe tempo na instalação e configuração de drivers externos, ele também pode ser perfeito para o desenvolvimento. É mais rápido do que acessar os dados diretamente do servidor de banco de dados.
Para usar o driver do file, adicione o seguinte código ao seu arquivo .env:
CACHE_DRIVER=file
2. Array
O driver array é um back-end de cache perfeito para executar testes automáticos e é configurado facilmente com Github Actions, Jenkins, etc.
O back-end do array armazena os dados em cache em um array em PHP e não requer que você instale ou configure nenhum driver. Ele funciona perfeitamente para testes automatizados, e é um pouco mais rápido que o back-end do cache de arquivos.
Para usar o driver array , adicione o seguinte código ao seu arquivo .env:
CACHE_DRIVER=array
3. Database
Ao usar o driver database, os dados são armazenados na memória para o processo PHP atual. Portanto, você precisa criar uma tabela de banco de dados para armazenar os dados em cache. Além disso, o cache de melhora a escalabilidade, distribuindo a carga de trabalho da consulta a partir do back-end para múltiplos frontends.
Você pode executar este comando Artisan — php artisan cache:table
— para auto-gerar o esquema de base de dados necessário para o driver database.
O driver database é usado principalmente em situações em que você pode instalar qualquer software na sua plataforma de hospedagem.
Por exemplo, digamos que você está usando um plano de hospedagem gratuito com opções limitadas. Para isso, sugerimos ficar com o driver file porque o driver database é, na maioria dos casos, o ponto mais fraco do seu aplicativo, e tentar empurrar mais dados para esse gargalo não é uma boa idéia.
Para usar o driver database, adicione o seguinte código ao seu arquivo .env:
CACHE_DRIVER=database
4. Redis
O driver redis usa a tecnologia de cache baseada na memória chamada . Embora seja rápido em comparação com os outros drivers de cache discutidos acima, ele requer a instalação e configuração de tecnologia externa.
Para usar o driver redis, adicione o seguinte código ao seu arquivo .env:
CACHE_DRIVER=redis
5. Memcached
Memcached é conhecida por ser a mais popular loja de cache baseada em memória. Se você não se importa com um pouco de manutenção extra do servidor (ter que instalar e manter serviços adicionais), os drivers de cache baseados em memória Memcached são ótimas opções.
O uso do driver memcached requer que o pacote PECL Memcached seja instalado.
Para usar o driver memcached, adicione o seguinte código ao seu arquivo .env.
CACHE_DRIVER=memcached
O melhor driver de cache para usar e o desempenho do driver de cache dependem do caso de uso do seu projeto e da quantidade de dados a serem recuperados.
Uso e métodos do cache do Laravel
O cache do Laravel fornece muitos métodos valiosos usados para implementar muitas estratégias de cache.
Abaixo listaremos e explicaremos os diferentes métodos (categorizados de acordo com o caso de uso):
put()
get()
many()
putMany()
increment()
decrement()
forever()
forget()
flush()
remember()
rememberForever()
Armazenamento de Cache
O armazenamento de novos dados no cache é muito simples usando os diferentes métodos, cada um com vários casos de uso.
1. Cache::put()
Este método aceita três parâmetros-chave, duration e data a serem armazenados em cache.
Vamos dar uma olhada em como usar Cache::put()
:
Cache::put(key, data, duration)
$post = Post::find(1);
Cache::put('post_1', $post, 20);
O código acima irá armazenar o post com a chave única por 20 segundos.
2. Cache::putMany()
Este método armazena um conjunto de dados no cache de uma só vez com a mesma duração. Ele aceita dois parâmetros que são data e seconds.
Vamos dar uma olhada em como usar Cache::putMany()
:
Cache::putMany(data, duration) // syntax
$posts = Post::all();
Cache::putMany($posts, 20);
3. Cache::remember()
Este método é outra excelente forma de implementar a estratégia de cache Aside. O método Cache::remember()
aceita três parâmetros, uma key, seconds e closure usados para recuperar dados da base de dados se não forem encontrados.
Vamos dar uma olhada em como usar Cache::remember()
:
Cache::remember(key, duration, closure) // syntax
Cache::remember('posts', 20, function(){
return Post::all();
});
O cache do Laravel também tem o método Cache::rememberForever()
, que não aceita o parâmetro seconds e armazena o data para sempre.
4. Cache::forever()
Este método armazena os dados no servidor cache para sempre sem especificar qualquer duração. Você pode implementá-lo com o seguinte código:
Cache::forever(key, data)
$post = Post::find(1);
Cache::forever('post_1', $post);
Recuperando dados de cache
Os métodos nesta categoria recuperam os dados de cache. Alguns destes métodos podem comportar-se de forma diferente, dependendo se os dados são encontrados ou não.
1. Cache::get()
Este método recupera dados do servidor de cache com uma chave específica. Você pode recuperar um item usando o código abaixo:
Cache::get(key) // syntax
$posts = Cache::get('posts');
2. Cache::many()
Este método é similar ao Cache::putMany()
. Ele é usado para recuperar um array de dados em cache de uma vez usando um array das chaves em cache. Você pode recuperar um array de cache usando o seguinte código:
Cache::many(keys) // syntax
const $keys = [
'posts',
'post_1',
'post_2'
];
$posts = Cache::many($keys);
3. Cache::remember()
Você também pode usar este método para recuperar dados em cache, verificando o servidor de cache usando a chave fornecida. Se os dados estiverem armazenados no cache, ele os recuperará. Caso contrário, ele recuperará os dados do servidor de banco de dados e os armazenará em cache. Este método é o mesmo que o método Cache::rememberForever()
com apenas um parâmetro de seconds extra no método Cache::remember()
.
Remoção de itens do cache
Os métodos sob esta categoria são usados para remover itens de cache, agrupados por funcionalidade.
1. Cache::forget()
Este método remove um único item do cache com um parâmetro-chave especificado:
Cache::forget('key');
2. Cache::flush()
Este método remove um único item do cache com um parâmetro chave especificado:
Cache::flush();
Valores de cache de incremento e desincremento
Você pode ajustar os valores de um valor inteiro armazenado no seu cache usando os métodos de incremento e decremento, respectivamente:
Cache::increment('key');
Cache::increment('key', $amount);
Cache::decrement('key');
Cache::decrement('key', $amount);
O cache do Laravel tem muitos grandes métodos que não discutimos acima, mas os métodos acima são populares. Você pode obter uma visão geral de todos os métodos na documentação oficial do cache do Laravel.
Configuração
O Laravel fornece uma API unificada para vários sistemas de cache. A configuração do cache do laravel fica em config/cache.php
. Neste arquivo você pode especificar o driver que você gostaria de usar por padrão em toda a sua aplicação. O Laravel suporta ferramentas como Memcached e Redis.
O arquivo de configuração do cache também contém várias outras opções, que são documentadas dentro do arquivo. Sendo assim, certifique-se de ler estas opções. Por padrão, o Laravel é configurado para usar o drive file
, que armazena objetos serializados no sistema de arquivos. Para grandes aplicações, recomenda-se que você utilize uma cache de in-memory(Verificar esse termo) como Memcached ou APC. Você pode ter várias configurações de cache para o mesmo driver.
Antes de usar o Redis com o Laravel, vc precisará instalar o pacote predis/predis
(~1.0) via Composer.
Uso do Cache
Gravando um item no Cache
Cache::put('key', 'value', $minutes);
Usando objetos do Carbon para a expiração
$expiresAt = Carbon::now()->addMinutes(10);
Cache::put('key', 'value', $expiresAt);
Gravando um item no Cache caso ele não exista
Cache::add('key', 'value', $minutes);
O método add
retornará true
se o item foi realmente adicionado para o cache. Caso contrário, retornará false
.
Verificando se um Cache existe
if (Cache::has('key'))
{
//
}
Recuperando um item do Cache
$value = Cache::get('key');
Recuperando um item ou retornando um valor default
$value = Cache::get('key', 'default');
$value = Cache::get('key', function() { return 'default'; });
Gravando um item no Cache permanentemente
Cache::forever('key', 'value');
Algumas vezes você pode querer recuperar um item do cache, mas também armazenar um valor default se o item requisitado não existir. Você pode fazer isto utilizando o método Cache::remember
:
$value = Cache::remember('users', $minutes, function()
{
return DB::table('users')->get();
});
Você também pode combinar os métodos remember
e forever
:
$value = Cache::rememberForever('users', function()
{
return DB::table('users')->get();
});
Note que todos os itens gravados no cache são serializados, neste caso, você fica livre para armazenar qualquer tipo de dado.
Puxando um item do Cache
Se você precisar recuperar um item do cache e, em seguida, deletá-lo, você pode usar o método pull
:
$value = Cache::pull('key');
Removendo um item do Cache
Cache::forget('key');
Access Specific Cache Stores
When using multiple cache stores, you may access them via the store
method:
$value = Cache::store('foo')->get('key');
Incrementando & Desincrementando
Todos os drivers, exceto database
, suportam as operações increment
e decrement
:
Incrementando um valor
Cache::increment('key');
Cache::increment('key', $amount);
Desincrementando um valor
Cache::decrement('key');
Cache::decrement('key', $amount);
Marcações de Cache
Nota: As marcações de cache, não são suportadas quando se usam os drivers
file
oudatabase
. Além disso, quando usamos várias marcações em caches que são armazenados "para sempre", o desempenho será melhor com um driver comomemcached
, que limpa automaticamente registros obsoletos.
Acessando um Cache com uma marcação
As marcações, permitem que você marque os items relacionados ao cache, em seguida, limpe todos os caches marcados com um nome dado. Para acessar um cache marcado, use o método tags
.
Você pode armazenar um cache passando um array dos nomes das marcações como argumentos ou como um array com os nomes das marcações:
Cache::tags('people', 'authors')->put('John', $john, $minutes);
Cache::tags(['people', 'artists'])->put('Anne', $anne, $minutes);
Você pode usar qualquer método de armazenamento de cache em combinação com as marcações, incluindo remember
, forever
e rememberForever
. Você também pode acessar itens que estão no cache oriundos das marcações de cache, também pode usar outros métodos de cache como increment
e decrement
.
Acessando items em um Cache marcado
Para acessar um cache marcado, passe o array das tags usadas anteriormente para armazenar.
$anne = Cache::tags('people', 'artists')->get('Anne');
$john = Cache::tags(['people', 'authors'])->get('John');
Você pode limpar todos os itens marcados com um nome ou array de nomes. Por exemplo, nesta declaração removeremos todas as marcações de cache com people
, author
ou ambos. Então, "Anne" e "John" seriam removidos do cache:
Cache::tags('people', 'authors')->flush();
Sendo assim, este outro código removerá somente caches marcados com authors
. Então "John" será removido, mas "Anne", não.
Cache::tags('authors')->flush();
Eventos Cache
Para executar código em todas as operações de cache, você pode escutar (ou rastrear, procurar) por eventos disparados pelo cache:
Event::listen('cache.hit', function($key, $value) {
//
});
Event::listen('cache.missed', function($key) {
//
});
Event::listen('cache.write', function($key, $value, $minutes) {
//
});
Event::listen('cache.delete', function($key) {
//
});
Cache do banco de dados
Quando usar o drive de cache database
, você precisará configurar uma tabela no que contém os itens do cache. Veja um exemplo Schema
abaixo:
Schema::create('cache', function($table)
{
$table->string('key')->unique();
$table->text('value');
$table->integer('expiration');
});
Memcached Cache
Usar o Mencached cache requere que o Pacote Memcached PECL seja instalado.
Por padrão configuração usa TCP/IP baseado no Memcached::addServer: 'memcached' => array( array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100), ),
Você pode também definir a opção host
para um caminho de socket UNIX. Se você fizer isto, a opção port
deve ser definida com o valor 0
:
'memcached' => array(
array('host' => '/var/run/memcached/memcached.sock', 'port' => 0, 'weight' => 100),
),
Estratégias de cache do Laravel
Dependendo do caso de uso do seu aplicativo e da estrutura de dados, é provável que várias estratégias de cache diferentes estejam disponíveis para você. Você pode até mesmo criar uma estratégia personalizada para atender às suas necessidades. Abaixo veremos a lista de estratégias de cache populares que você pode implementar em seu projeto Laravel.
writeThrough
Na estratégia writeThrough, o servidor de cache fica entre os pedidos e o servidor de banco de dados, fazendo com que cada operação de gravação passe pelo servidor de cache antes de ir para o servidor de banco de dados. Assim, a estratégia de cache writeThrough é semelhante à estratégia readThrough.
Você pode implementar esta estratégia com o cache do Laravel com o seguinte código:
public function writeThrough($key, $data, $minutes) {
$cacheData = Cache::put($key, $data, $minutes)
// Database Server is called from(after) the Cache Server.
$this->storeToDB($cachedData)
return $cacheData
}
private function storeToDB($data){
Database::create($data)
return true
}
writeBack (writeBehind)
Esta estratégia é uma forma mais avançada de implementar a estratégia writeThrough, acrescentando atrasos nas operações de escrita.
Você também pode chamar isso de estratégia de writeBehind devido ao atraso no tempo aplicado ao servidor de cache antes de escrever os dados para o servidor de banco de dados.
Você pode implementar esta estratégia com o cache do Laravel com o seguinte código:
$durationToFlush = 1; // (in minute)
$tempDataToFlush = [];
public function writeBack($key, $data, $minutes){
return $this->writeThrough($key, $data, $minutes);
}
public function writeThrough($key, $data, $minutes) {
$cacheData = Cache::put($key, $data, $minutes);
$this->storeForUpdates($cacheData);
return $cacheData;
}
// Stores new data to temp Array for updating
private function storeForUpdates($data){
$tempData = {};
$tempData['duration'] = this.getMinutesInMilli();
$tempData['data'] = data;
array_push($tempDataToFlush, data);
}
// Converts minutes to millisecond
private function getMinutesInMilli(){
$currentDate = now();
$futureDate = Carbon(Carbon::now()->timestamp + $this->durationToFlush * 60000)
return $futureDate->timestamp
}
// Calls to update the Database Server.
public function updateDatabaseServer(){
if($this->tempDataToFlush){
foreach($this->tempDataToFlush as $index => $obj){
if($obj->duration timestamp){
if(Database::create($obj->data)){
array_splice($this->tempDataToFlush, $index, 1);
}
}
}
}
}
O método writeBack chama para o método writeThrough, que armazena os dados no servidor de cache e um array temporário para ser empurrado posteriormente para o servidor de banco de dados usando o método updateDatabaseServer. Você pode configurar um CronJob para atualizar o servidor de banco de dados a cada cinco minutos.
writeAround
Esta estratégia permite que todas as operações de escrita vão diretamente para o servidor de banco de dados sem atualizar o servidor de cache – somente durante as operações de leitura é que o servidor de cache é atualizado.
Assumindo que um usuário deseja criar um novo Article, o Articlearmazena diretamente no servidor do banco de dados. Quando o usuário deseja ler o conteúdo do Article pela primeira vez, o Article é recuperado do servidor do banco de dados e atualiza o servidor de cache para solicitações subseqüentes.
Você pode implementar esta estratégia com o cache do Laravel com o seguinte código:
public function writeAround($data) {
$storedData = Database::create($data);
return $storedData;
}
public function readOperation($key, $minutes){
$cacheData = Cache::remember($key, $minutes, function() {
return Article::all();
})
return $cacheData;
}
Cache aside (Carregamento preguiçoso)
Nesta estratégia, o banco de dados é posto de lado e o aplicativo solicita primeiro os dados do servidor de cache. Então, se houver um acerto (encontrado), os dados são devolvidos ao cliente. Caso contrário, se houver um erro (não encontrado), o servidor de banco de dados solicita os dados e atualiza o servidor de cache para solicitações subseqüentes.
Você pode implementar esta estratégia com o cache do Laravel com o seguinte código:
public function lazyLoadingStrategy($key, $minutes, $callback) {
if (Cache::has($key)) {
$data = Cache::get($key);
return $data;
} else {
// Database Server is called outside the Cache Server.
$data = $callback();
Cache::set($key, $data, $minutes);
return $data;
}
}
O código acima mostra a implementação do cache Aside Strategy, que é equivalente à implementação do método Cache::remember.
Read through
Esta estratégia é o oposto direto da estratégia do cache Aside. Nesta estratégia, o Servidor de cache fica entre o Pedido do Cliente e o Servidor de Base de Dados.
As solicitações vão diretamente para o servidor de cache, e o servidor de cache é responsável por recuperar os dados do se não forem encontrados no servidor de cache.
Você pode implementar esta estratégia com o cache do Laravel com o seguinte código:
public function readThrough($key, $minutes) {
$data = Cache::find($key, $minutes);
return $data;
}
private function find($key, $minutes){
if(Cache::has($key);){
return Cache::get($key);
}
// Database Server is called from the Cache Server.
$DBdata = Database::find($key);
Cache:put($key, $DBdata, $minutes);
return $DBdata;
}
Aí está! Agora discutimos algumas estratégias populares de cache para o seu próximo aplicativo Laravel. Lembre-se, você pode até usar uma estratégia de cache personalizada que melhor se adapte aos requisitos do seu projeto.
Cache da interface do usuário (UI) de um aplicativo Laravel
O cache da interface do usuário de um aplicativo Laravel é um conceito conhecido como Full Page Cache (FPC). Este termo se refere ao processo de cache da resposta HTML de um aplicativo.
É excelente para aplicativos onde os dados HTML dinâmicos não mudam com frequência. Você pode fazer o cache da resposta HTML para uma resposta geral e uma renderização mais rápida do HTML.
Nós podemos implementar o FPC com a seguinte linha de código:
class ArticlesController extends Controller {
public function index() {
if ( Cache::has('articles_index') ) {
return Cache::get('articles_index');
} else {
$news = News::all();
$cachedData = view('articles.index')->with('articles', $news)->render();
Cache::put('articles_index', $cachedData);
return $cachedData;
}
}
}
À primeira vista, você deve ter notado que nós verificamos se essa página de articles_index já existe no nosso servidor cache. Então retornamos a página renderizando-a com os métodos view() e render() do Laravel.
Caso contrário, nós renderizamos a página e armazenamos a saída no nosso servidor de cache para pedidos subsequentes antes de devolver a página renderizada ao navegador.
Outros:
$peopleCount = Cache::remember('people', 60, function () {
return People::where('status', 'active')->count();
});
***
Cache::remember('people', 60, function () {
return People::where('status', 'active')->count();
});
return Cache::get('people');
Fontes:
- https://laracasts.com/discuss/channels/laravel/laravel-cacheremember-and-cacheget
- https://kinsta.com/pt/blog/cache-do-laravel/
- https://laravel-docs-pt-br.readthedocs.io/en/latest/cache/
Donate to Site
Renato
Developer