Caching in Kotlin: Redis, Memcached und integrierte Lösungen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum Caching für hochlastige Kotlin-Anwendungen kritisch ist

In der modernen Kotlin-Entwicklung, insbesondere im Bereich Microservices und Backend-Anwendungen, ist Leistung eine Schlüsselanforderung. Caching ermöglicht es, die Antwortzeit drastisch zu verkürzen, die Last auf Datenbanken und externe APIs zu reduzieren sowie die Infrastrukturkosten zu senken. Auf fortgeschrittener Ebene sollte ein Entwickler nicht nur einen Cache implementieren, sondern die optimale Strategie je nach Szenario auswählen: verteilter Cache (Redis, Memcached) oder In-Memory-Lösungen (Caffeine, Guava). In diesem Artikel analysieren wir fortgeschrittene Techniken für die Arbeit mit Caching in Kotlin, einschließlich der Integration mit Coroutines, der Konfiguration von TTL und Invalidierungsmustern.



1. Redis in Kotlin: Fortgeschrittene Arbeit mit Lettuce und Redisson

1.1. Asynchrones Caching mit Lettuce

Die Bibliothek Lettuce ist der De-facto-Standard für die Arbeit mit Redis aus Kotlin, dank der vollständigen Unterstützung reaktiver und asynchroner Streams. Auf fortgeschrittener Ebene ist es wichtig, die Suspendable API über Coroutines zu nutzen.

import io.lettuce.core.RedisClientimport io.lettuce.core.api.coroutinesimport kotlinx.coroutines.flow.Flowimport kotlinx.coroutines.flow.map

class RedisCache(private val client: RedisClient) { private val connection = client.connect() private val commands = connection.coroutines() // Coroutine-API

suspend fun get(key: String): String? = commands.get(key)

suspend fun set(key: String, value: String, ttlSeconds: Long = 60) { commands.setex(key, ttlSeconds, value) }

suspend fun invalidate(pattern: String) { val keys = commands.keys(pattern) if (keys.isNotEmpty()) commands.del(*keys.toTypedArray()) }}

Fortgeschrittener Tipp: Verwenden Sie SCAN anstelle von KEYS für die Produktion, um eine Blockierung von Redis bei großen Datensätzen zu vermeiden.



1.2. Redisson: Verteilte Sperren und Cache mit lokaler Ebene

Redisson bietet eine höherwertige API, einschließlich verteilter Sperren und eines zweistufigen Caches (Redis + lokaler Caffeine). Dies ist ideal für Szenarien, in denen Datenkonsistenz kritisch ist.

import org.redisson.Redissonimport org.redisson.config.Configimport org.redisson.api.RLocalCachedMap

class RedissonCache { private val config = Config().apply { useSingleServer().address = "redis://localhost:6379" } private val client = Redisson.create(config)

fun getCachedMap<K, V>(name: String): RLocalCachedMap<K, V> { return client.getLocalCachedMap(name, LocalCachedMapOptions.defaults()) }}


2. Memcached in Kotlin: Leichtgewichtiges Protokoll und hohe Geschwindigkeit

2.1. Verbindung über xmemcached

Memcached bleibt eine ausgezeichnete Wahl für einfaches Schlüssel-Wert-Caching ohne Persistenzbedarf. Die Bibliothek xmemcached bietet hohe Leistung und Unterstützung für das Text-/Binärprotokoll.

import net.rubyeye.xmemcached.MemcachedClientBuilderimport net.rubyeye.xmemcached.XMemcachedClientimport kotlinx.coroutines.Dispatchersimport kotlinx.coroutines.withContext

class MemcachedCache(private val client: XMemcachedClient) { suspend fun get(key: String): Any? = withContext(Dispatchers.IO) { client.get(key) }

suspend fun set(key: String, value: Any, ttl: Int = 3600) = withContext(Dispatchers.IO) { client.set(key, ttl, value) }}

Wichtig: Memcached unterstützt keine komplexen Datenstrukturen. Verwenden Sie daher für Listen oder Hashes Redis oder eine Serialisierung in JSON.



2.2. Optimierung mit dem binären Protokoll

Aktivieren Sie auf fortgeschrittener Ebene das binäre Protokoll, um den Overhead durch die Befehlsanalyse zu reduzieren:

val builder = Memcach                

Blogs

Buchempfehlungen