Substituindo o Redis pelo Valkey em projetos PHP/Hyperf
Tags: redis, valkey, php, webdev
Published: 2024-05-21 02:12:25

## Licença Redis

Recentemente, o Redis estava disponível sob a **Licença Pública Geral Affero** (AGPL), uma licença de código aberto que exigia que qualquer software modificado usando o Redis também fosse distribuído sob os termos da AGPL. Isso significava que qualquer empresa que construísse um produto sobre o Redis e o modificasse de alguma forma tinha a obrigação de compartilhar essas modificações com a comunidade.

O novo modelo de licenciamento do Redis baseia-se em duas novas licenças: a **Redis Source Available License** (RSAL) e a **Redis Commons Clause**. A RSAL permite o acesso ao código-fonte do Redis, mas com restrições sobre sua utilização. Já a **Redis Commons Clause**, uma adição à RSAL, impõe restrições adicionais, proibindo o uso comercial do software em determinados contextos, a menos que uma licença comercial seja adquirida.

## Alternativas

Existem alternativas como Memcached, DynamoDB, entre outros. Todos estes mencionados podem gerar reescrita de código, dependendo do formato no qual o projeto foi escrito. Para evitar os problemas mencionados anteriormente, apresento o [Valkey](https://github.com/valkey-io/valkey).

O Valkey trata-se basicamente de um fork do Redis, logo, a lógica de implementação continua a mesma. O "pulo do gato" está em relação ao tipo de licença, que permite a comercialização por estar ligada a `Copyright (c) 2024-present, Valkey contributors` e `Copyright (c) 2006-2020, Salvatore Sanfilippo`.

## Implementação

Mas e agora? Como proceder em meu projeto PHP?

Irei apresentar um exemplo utilizando o framework Hyperf, mas nada impede a implementação também no Laravel, Symfony, ou qualquer outro framework que utiliza conectores Redis.

O `docker-compose.yml` abaixo realiza o pull da imagem `valkey/valkey`, possibilitando o uso no container de uma aplicação `Hyperf`:

```yml
version: "3"

name: redis-to-valkey

services:
  hyperf-valkey:
    build: ./
    container_name: hyperf-valkey
    ports:
      - 9501:9501
    depends_on:
      - valkey
    restart: always

  valkey:
    container_name: valkey
    image: valkey/valkey
    ports:
      - 6379:6379
```

O backend `hyperf-valkey` é construído com base no Dockerfile abaixo (instalando também a extensão interface [redis-php](https://pecl.php.net/package/redis):

```docker
FROM php:8.2

RUN apt-get update && apt-get install --no-install-recommends -y \
    wget \
    vim \
    git \
    unzip

RUN apt-get update \
    && apt-get install --no-install-recommends -y \
    libzip-dev \
    libcurl4-openssl-dev \
    libssl-dev \
    libpq-dev \
    libjpeg-dev \
    libpng-dev \
    libfreetype6-dev \
    g++ \
    libaio-dev \
    libicu-dev

RUN curl -sS https://getcomposer.org/installer | php -- \
    --install-dir=/usr/local/bin \
    --filename=composer

RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \
    && pecl install redis \
    && printf "no\nyes\nno\nyes\n" | pecl install swoole \
    && echo "swoole.use_shortname = Off" >> /usr/local/etc/php/conf.d/swoole.ini \
    && docker-php-ext-install \
    pcntl \
    gd \
    && docker-php-ext-enable \
    redis \
    swoole

EXPOSE 9501
```

Após isso, acesse o container via `bash` ou `remote containers` e crie o projeto:

```
composer create-project hyperf/hyperf-skeleton
```

No questionamento `Do you want to use Redis Client?`, selecione `y`

![Do you want to use Redis Client?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/04e0fa79runboedjez1p.png)

No arquivo `.env`, altere as chaves REDIS para:

```
REDIS_HOST=valkey
REDIS_AUTH=(null)
REDIS_PORT=6379
REDIS_DB=0
```

Com isso, a conexão Valkey com o projeto Hyperf já está concluída. Para utilizar a funcionalidade de cache com o Valkey, vamos acessar a `IndexController.php` e substituir o conteúdo existente pelo código abaixo:

```php
<?php

declare(strict_types=1);

namespace App\Controller;

use Hyperf\Redis\Redis as Valkey;

class IndexController extends AbstractController
{
    public function __construct(protected Valkey $valkey)
    {
    }

    public function index()
    {
        $content = 'hello valkey!';
        $key = 'cache';
        $this->valkey->set($key, $content);

        return [$this->valkey->get($key)];
    }
}
```

Inicie a aplicação com `php bin/hyperf.php start`, acessando posteriormente o endereço http://127.0.0.1:9501, tendo como retorno:

![Hello Valkey](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkjb6m0xmevhr0rc9mzl.png)

## Considerações

Para projetos em andamento que já estão utilizando o Redis, basta substituir o host Redis pelo serviço Valkey (via container, como exemplificado). Além disso, projetos Laravel podem seguir a mesma lógica utilizando a biblioteca `predis/predis`.

O ideal pela questão de nomenclaturas e responsabilidades, seria utilizar/criar pacotes específicos para o Valkey, já que provavelmente receberá modificações específicas ao longo do tempo, distanciando um pouco a equivalência com o projeto Redis. Contudo, a solução apresentada neste artigo é viável.

### Referências
- [Redis](https://redis.io/legal/licenses)
- [Licenças](https://medium.com/@darioajr/o-novo-licenciamento-do-redis-e-seu-impacto-no-mercado-81c1ae11e1cd)
- [Hyperf](https://hyperf.wiki/3.1/#/en)
- [Docker Hyperf](https://github.com/hyperf/hyperf-docker)
- [Valkey](https://github.com/valkey-io/valkey)
- [Docker Valkey](https://hub.docker.com/r/valkey/valkey)