Blog

Digging Into Magento 2's Partial Reindexing Implementation

Published: February 13, 2017

Tags:

Partial reindexing was only a thing in Enterprise Edition of Magento 1. In Magento 2, however, it’s part of Community Edition. While the overall architecture is pretty much the same, as with all of Magento 2, the code is very different. In this post I’ll dig through Magento 2’s core code to investigate the implementation.

NOTE: This post is based on the Magento 2.1.4 code base.

Magento's REQUEST_PATH FPC Tag

Published: February 6, 2017

When Magento saves data to cache, it has the option to add “tags” to the data it is saving. This feature, which is built into Zend Framework 1, is particularly useful as it allows the application easily invalidate all data associated with a particular tag.

For example, when the name of a product changes, all pages on which that product was displayed can be invalidated by passing the appropriate tag to the cache instance’s clean method. If the product with entity_id 1 had changed, cleaning all cache data would look like this…

Enterprise_PageCache_Model_Cache::getCacheInstance()
    ->clean('CATALOG_PRODUCT_1');

One tag that Magento’s Enterprise_PageCache module makes uses of is the REQUEST_PATH tag. In this post, we’ll first explore how Magento uses this tag out-of-box. Then, we’ll take a look at how we can take advantage of this tag.

Mage::getStoreConfig() in tight loops

Published: February 2, 2017

Recently, while doing some profiling of an uncached category page, I noticed something funny…A sizable amount of time being spent on Mage::getStoreConfig().

Digging in, I saw that it was coming from the navigation module. It contained a function called getAllFilterableOptionsAsHash, which builds a map of URL keys (using it’s own logic) to Magento attribute option IDs. It looks something like this (abbreviated for simplicity’s sake)…

public function getAllFilterableOptionsAsHash()
{
    $hash = array();

    $attributes = $this->getFilterableAttributes();

    $options = $this->getAllOptions();

    foreach ($attributes as $a) {
        $hash[$a->getAttributeCode()] = array();
        foreach ($options as $o){
            if (o['attribute_id'] == $a->getId()) {
                $key = $this->createKey($o['url_alias']);
                $key .= Mage::getStoreConfig('module/part/special_char');
                $hash[$code][$key] = $o['option_id'];
            }
        }
    }

    return $hash;
}

In this case getAllFilterableAttributes will return all attributes that are filterable and getAllOptions will return all options for filterable attributes. On the site in question there were 18 filterable attributes with ~4250 options.

Based on the code above, this means Mage::getStoreConfig('module/part/special_char'); will be called ~4250 times. I began to wonder what the benefit might be of caching the value in an temporary value, rather than calling Mage::getStoreConfig over and over. Here, I’ll share the results of my investigation…

How Partial Reindexing Schedule Impacts Page Cache Hit Rate

Published: January 30, 2017

One factor that impacts your Magento site’s full page cache hit rate is your partial reindexing schedule. By partial reindexing, I mean execution of the enterprise_refresh_index job, which runs when the Magento cron is executed in “always” mode.

Let’s take a closer look at the interplay between partial reindexing and full page cache hit rate.

HTTP Response Header Size Limits

Published: January 24, 2017

A while back I published a post about HTTP request header size limits. At the time, I had just finished remediating an issue where requests were being blocked by a WAF for exceeding the “max header size” policy.

Recently, I’ve been dealing with a similar, but slightly different issue…requests failing due to the size of the response headers. Here, I’ll document my findings on this issue…

MySQL Query Cache Hit Rate

Published: January 22, 2017

MySQL’s query cache is a useful tool to improve performance and scalability. However, if not implemented correctly, it can do more harm than good…

The query cache offers the potential for substantial performance improvement, but do not assume that it will do so under all circumstances. With some query cache configurations or server workloads, you might actually see a performance decrease.

https://dev.mysql.com/doc/refman/5.7/en/query-cache.html

One critical data point to look at when measuring the effectiveness of query caching is the query cache hit rate. Let’s take a look at how to do that.