Skip to content

Latest commit

 

History

History
87 lines (63 loc) · 3.06 KB

2022-03-25-redis-cart-persister.md

File metadata and controls

87 lines (63 loc) · 3.06 KB
title date area tags
Redis cart persister
2022-03-25
checkout
checkout
cart
redis
performance

Redis cart persister

::: info This document represents an architecture decision record (ADR) and has been mirrored from the ADR section in our Shopware 6 repository. You can find the original version here ::: With the last benchmarks it became clear how cost intensive the loading and saving of the shopping cart to and from the database is. A detailed analysis revealed two problems:

  1. Every time the shopping cart is loaded, it is written back to the database after validation. However, this leads to a write on the connection which causes us to lose support for master-slave database setups.
  2. To ensure the best possible performance, the shopping cart is written to the database as a serialized object. However, this in turn leads to rather high amounts of data having to be sent through the internal network.

To solve these problems, we implemented the Shopware\Core\Checkout\Cart\RedisCartPersister:

<?php declare(strict_types=1);

namespace Shopware\Core\Checkout\Cart;

class RedisCartPersister extends AbstractCartPersister
{
    /**
     * @var \Redis|\RedisCluster
     */
    private $redis;

    private EventDispatcherInterface $eventDispatcher;

    private bool $compress;

    public function load(string $token, SalesChannelContext $context): Cart {}

    public function save(Cart $cart, SalesChannelContext $context): void {}

    public function delete(string $token, SalesChannelContext $context): void {}

    public function replace(string $oldToken, string $newToken, SalesChannelContext $context): void {}
}

This stores the cart inside redis, which can be configured via the config in config/packages/*.yaml:

shopware:
    cart:
        redis_url: 'redis://redis'

If no redis connection is configured, the redis cart persister is removed from the DI container. This is done inside the \Shopware\Core\Checkout\DependencyInjection\CompilerPass\CartRedisCompilerPass:

<?php declare(strict_types=1);

namespace Shopware\Core\Checkout\DependencyInjection\CompilerPass;

class CartRedisCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if (!$container->getParameter('shopware.cart.redis_url')) {
            $container->removeDefinition('shopware.cart.redis');
            $container->removeDefinition(RedisCartPersister::class);

            return;
        }

        $container->removeDefinition(CartPersister::class);
        $container->setAlias(CartPersister::class, RedisCartPersister::class);
    }
}

In addition, to reduce network traffic, we used cache compression, which significantly reduces the amount of data to be sent. However, the compression can be deactivated again via config/packages/*.yaml:

shopware:
    cart:
        compress: false

Notice: Currently there is no migration path to transfer shopping carts from one storage to the other.