[Este blog foi distribuído pelo site http://nitschinger.at/].
Esta postagem do blog apresenta uma introdução sobre como você pode acelerar a camada ORM do Doctrine usando o Couchbase Server 2.0 como um cache simples, rápido e elástico na frente de suas entidades.
Motivação
Como parte de nossos esforços contínuos para tornar o Couchbase mais integrado a estruturas e bibliotecas, adicionamos suporte de cache para o
ORM do Doctrine. Recentemente, a solicitação pull foi mesclada ao ramo principal e está programada para ser publicada junto com a versão 2.4.
O armazenamento em cache pode ser usado de forma autônoma (por meio da API fornecida por
doutrina/comum) ou integrado à funcionalidade ORM. Examinaremos as duas variantes por meio de exemplos simples; uma boa documentação também pode ser encontrada
aqui. Observe que, no momento da redação deste artigo, o CouchbaseCache não é mencionado como um driver de cache porque a documentação ainda precisa ser atualizada.
Como a versão 2.4 ainda não foi lançada, precisamos trabalhar com a versão
2.4.x-dev ramo. Usaremos o
Compositor para buscar nossas dependências, portanto, basta alterar o número da versão se quiser fixá-lo na versão 2.4 posteriormente.
Cache simples
Nosso primeiro exemplo mostra como a API de cache pode ser usada diretamente. Se você estiver familiarizado com a API do Couchbase, poderá pensar que se trata mais ou menos de uma API diferente com a mesma (e talvez menos) semântica, mas a questão é que ela usa a interface da API de cache do Doctrine e, como resultado, você pode alternar entre diferentes implementações de cache com muita facilidade.
Crie um diretório chamado couchbase-doctrine-simple com o seguinte composer.json dentro:
{
"exigir": {
"doutrina/comum": "2.4.x-dev",
"ext-couchbase": "1.1.x"
}
}
Isso instala o
doutrina/comum e também garante que temos o pacote
couchbase.so no lugar. Se você ainda não instalou a extensão PHP do Couchbase, vá para o diretório
site oficial e instalá-lo com base no tutorial e na documentação.
Criar um index.php com o seguinte conteúdo (dividiremos o código posteriormente):
// 0: Autoloader do compositor
exigir 'vendor/autoload.php';
// 1: Abrir a conexão com o Couchbase
$couchbase = novo Couchbase(“127.0.0.1”, “”, “”, "default");
// 2: Instanciar o driver e injetar a conexão
$cacheDriver = novo DoctrineCommonCacheCouchbaseCache();
$cacheDriver->setCouchbase($couchbase);
// 3: Execute seus comandos!
$key = "my-cache-item";
se(!$cacheDriver->contém($key)) {
$cacheDriver->salvar($key, "my_data");
} mais {
eco $cacheDriver->buscar($key);
}
?>
Primeiro, precisamos inicializar o autoloader do composer para não precisarmos escrever todos os exigir por conta própria. A próxima coisa que precisamos fazer é realmente nos conectarmos ao cluster do Couchbase:
// 1: Abrir a conexão com o Couchbase
$couchbase = novo Couchbase(“127.0.0.1”, “”, “”, "default");
Aqui, estamos nos conectando a um nó no cluster que aponta para localhostmas você também pode passar uma matriz de nós. Nós nos conectamos ao padrão que não tem senha. Agora que temos nossa conexão estabelecida, podemos instanciar o driver de cache e injetar nosso cliente Couchbase:
// 2: Instanciar o driver e injetar a conexão
$cacheDriver = novo DoctrineCommonCacheCouchbaseCache();
$cacheDriver->setCouchbase($couchbase);
Daqui em diante, a API é a mesma para todos os drivers de cache. O código a seguir verifica se o cache contém uma chave. Se ela estiver presente, ele imprime o documento, mas se não estiver, cria um novo. Este é um exemplo muito simples, mas mostra como você pode começar a usar o cache do Couchbase em seus próprios projetos com apenas algumas linhas de bootstrapping!
Além desses três métodos, há também um excluir disponível. Por fim, você pode passar um terceiro parâmetro opcional em salvar com um $lifeTime para que o item do cache desapareça automaticamente.
Como o Couchbase Server não se importa com o que você armazena, você também pode salvar e buscar qualquer tipo de dado (além de recursos):
$cacheDriver->salvar($key, matriz('foo' => 'bar'));
var_dump($cacheDriver->buscar($key));
Observe que, quando você usar o driver nesse nível, tente armazenar cadeias de caracteres JSON sempre que possível (use json_encode/json_decode em suas estruturas de dados). Dessa forma, você pode aproveitar o novo mecanismo de visualização do Couchbase Server 2.0. Você também pode armazenar objetos serializados (como precisamos fazer com a integração ORM), já que para o Couchbase Server é apenas um fluxo de bytes.
Agora podemos nos basear nesse fundamento e ver como isso funciona com a integração do ORM.
Integração de ORM
Crie um novo diretório chamado couchbase-doctrine-orm com o seguinte composer.json:
{
"exigir": {
"doutrina/forma": "2.4.x-dev",
"doutrina/dbal": "2.4.x-dev",
"doutrina/comum": "2.4.x-dev",
"ext-couchbase": "1.1.x"
},
"autoload": {
"psr-0": {
"Entidades": "src/"
}
}
}
Desta vez, nosso composer.json é um pouco mais longo, porque precisamos definir todas as nossas dependências manualmente (já que não queremos trabalhar com a versão estável). Como precisamos definir as entidades do Doctrine, passamos ao autoloader do composer o diretório personalizado (src/).
A próxima coisa de que precisamos é a nossa entidade real que queremos gerenciar por meio do Doctrine. Vá em frente e crie um Pessoa.php dentro do arquivo src/Entidades com o seguinte conteúdo:
espaço de nome Entidades;
/** @Entity */
classe Pessoa {
/**
* @Id @Column(type="integer") @GeneratedValue(strategy="AUTO")
*/
privado $id;
/** @Column(type="string") */
privado $primeiro nome;
/** @Column(type="string") */
privado 1TP4Nome do apelido;
público função setFirstname($primeiro nome) {
1TP4Isso->primeiro nome = $primeiro nome;
}
público função getFirstname() {
retorno 1TP4Isso->primeiro nome;
}
público função setLastname(1TP4Nome do apelido) {
1TP4Isso->sobrenome = 1TP4Nome do apelido;
}
público função getLastname() {
retorno 1TP4Isso->sobrenome;
}
}
?>
Esta é uma entidade do Doctrine muito simples que tem algumas propriedades e também uma entidade
ID campo. Vou usar
SQLite no exemplo a seguir, mas fique à vontade para usar o MySQL ou qualquer outro banco de dados relacional que você tenha disponível.
Para conectar tudo, vamos criar um arquivo index.php no diretório raiz do projeto. Mais uma vez, aqui está o conteúdo completo e, depois, vamos separá-lo:
// Autoloader do compositor.
$loader = exigir 'vendor/autoload.php';
/**
* Inicializar o Couchbase e o cache.
*/
$couchbase = novo Couchbase(“127.0.0.1”, “”, “”, "default");
$cacheDriver = novo DoctrineCommonCacheCouchbaseCache();
$cacheDriver->setCouchbase($couchbase);
/**
* Inicializar o Gerenciador de Entidades.
*/
$paths = matriz(__DIR__ . '/src/Entidades/');
$isDevMode = verdadeiro;
$dbParams = matriz(
"motorista => 'pdo_sqlite',
'usuário' => "raiz,
'senha' => ”,
'caminho' => __DIR__ . '/cbexample.sqlite'
);
$config = DoctrineORMToolsSetup::createAnnotationMetadataConfiguration($paths, $isDevMode, nulo, $cacheDriver);
$em = Gerenciador de propriedades do DoctrineORMEntity::criar($dbParams, $config);
/**
* Trabalhar com nossas entidades.
*/
$person = novo EntidadesPessoa();
$person->setFirstname("Michael");
$person->setLastname("Nitschinger");
$em->persistir($person);
$em->descarga();
// Consulta com cache de resultados
$query = $em->createQuery('select p from EntitiesPerson p');
$query->useResultCache(verdadeiro);
$results = $query->getResult();
?>
Como isso pode ser muito difícil de entender, vamos dividi-lo em partes menores.
$couchbase = novo Couchbase(“127.0.0.1”, “”, “”, "default");
$cacheDriver = novo DoctrineCommonCacheCouchbaseCache();
$cacheDriver->setCouchbase($couchbase);
Depois de inicializarmos o carregador automático, estamos inicializando o driver de cache. Você já sabe o que isso significa porque usamos o mesmo código no exemplo simples anterior.
$paths = matriz(__DIR__
. '/src/Entidades/');
$isDevMode = verdadeiro;
$dbParams = matriz(
"motorista => 'pdo_sqlite',
'usuário' => "raiz,
'senha' => ”,
'caminho' => __DIR__
. '/cbexample.sqlite'
);
$config = DoctrineORMToolsSetup::createAnnotationMetadataConfiguration($paths, $isDevMode, nulo, $cacheDriver);
$em = Gerenciador de propriedades do DoctrineORMEntity::criar($dbParams, $config);
O Gerenciador de propriedades do DoctrineORMEntity é um dos principais blocos de construção do Doctrine e precisa ser inicializado adequadamente. Portanto, precisamos fornecer a ele uma configuração válida. Aqui, usaremos anotações (como visto na Entidade do Doctrine, mas você também pode fazer isso por meio de XML ou YAML). Também precisamos fornecer nossa conexão com o banco de dados e o caminho para as entidades. A parte importante aqui é que passamos a variável $cacheDriver para o método de fábrica. Isso inicializa automaticamente nosso CouchbaseCache a ser usado para todos os tipos de cache (cache de consulta, metadados e resultados).
Agora podemos ir em frente e criar um registro:
$person = novo EntidadesPessoa
();
$person->setFirstname("Michael");
$person->setLastname("Nitschinger");
$em->persistir($person);
$em->descarga();
Em seguida, podemos recuperá-lo por meio de uma consulta:
$query = $em->createQuery('select p from EntitiesPerson p');
$query->useResultCache(verdadeiro);
$results = $query->getResult();
Observe que explicitamente dizemos a ele para armazenar em cache esse resultado da consulta para nós (por padrão, o armazenamento em cache do resultado não será usado). Se abrir o navegador e apontá-lo para a interface de gerenciamento do Couchbase Server 2.0, você poderá ver que o Doctrine criou muitos documentos nos bastidores. Eles são usados posteriormente para aumentar o desempenho do seu aplicativo.
Resumo
Como você pode ver, usar o Couchbase como um cache para o Doctrine não é difícil. Você só precisa inicializá-lo e passá-lo para a configuração. A partir desse ponto, tudo acontece nos bastidores. E não se esqueça de que você não só obtém um desempenho excepcional, mas também persistência, escalabilidade e todas as coisas legais que o Couchbase Server fornece imediatamente.
Se você tiver alguma dúvida ou opinião, informe-me nos comentários! Por fim, obrigado a
Marco Pivetta por me ajudar a depurar um problema com a integração do ORM!