2020-10-05 12:17:08+00:00

Ingesting telemetry metrics from thousands of IoT devices produces continuous read/write load on your database. If dashboard users refresh their UI constantly, the backend will query the database repeatedly for the same device configuration states, causing datastore read spikes and high hosting costs. To optimize performance, backend architectures implement a Cache-Aside pattern using GAE's Memcache to serve read requests from memory.

By intercepting database lookups with Memcache writes, we can reduce database read queries by up to 90%.


1. Implementing the Cache-Aside Access Pattern

We write a database fetch helper that checks the cache first, falling back to Datastore queries only on cache misses:

# telemetry_cache.py
from google.appengine.api import memcache
from google.cloud import ndb

def get_device_configuration(device_id):
    cache_key = f"device_config_{device_id}"
    
    # Attempt to read from Memcache
    cached_config = memcache.get(cache_key)
    if cached_config:
        return cached_config
        
    # Query Datastore on cache miss
    client = ndb.Client()
    with client.context():
        config = DeviceConfig.query(DeviceConfig.device_id == device_id).get()
        
    if config:
        # Write to cache to speed up subsequent reads
        memcache.set(cache_key, config, time=600) # 10-minute cache lifetime
    return config

2. Write-Through Cache Invalidation

To prevent serving stale settings, the API handler deletes the corresponding Memcache key whenever a device configuration is updated, forcing the next read request to fetch fresh data.