Redis 7'den Redis 8.x'e ve Valkey 9'a: Yenilikler, Ayrışma Noktaları ve StackExchange.Redis 2→3 Geçişi
Redis 8'in yazdığı RDB dosyasını ne Redis 7.4 ne de Valkey 9 açabiliyor; Redis ile Valkey'in ortak noktası 7.2 ve yükseltme tek yönlü. Gerçek ölçümlerle RDB ve replication uyumluluğu, Redis 8.0–8.10 sürüm özeti, iki sunucuya COMMAND DOCS ile sorulmuş uyumluluk tablosu, StackExchange.Redis 3.x'te derleme hatasına dönen eski API'ler ve bir sürüm yükseltme planı.
Sürüm notu: Bu yazıdaki örnekler Redis 8.10.3 (redis:8), Redis 7.2.17 ve 7.4.12, Valkey 9.1.3, .NET 10 ve StackExchange.Redis 3.4.35 ile çalıştırılmıştır.
Önce Tahmin Et
Bookstore'un (sitedeki serilerin ortak örnek uygulaması, bir online kitapçı) Redis'ini bir sürümden diğerine ya da Redis'ten Valkey'e taşımanın en basit yolu RDB (Redis'in snapshot dosya formatı) dosyasını alıp yeni sunucuda açmak gibi görünüyor. lab/upgrade/rdb-compat.sh bir image ile üç key yazıp SAVE ediyor, oluşan dump.rdb'yi başka bir image ile açmaya çalışıyor. Sekiz kombinasyondan hangileri açılır?
sh lab/upgrade/rdb-compat.sh
redis:7.2 -> redis:8 REDIS0011 loaded, DBSIZE 3
redis:7-alpine -> redis:8 REDIS0012 loaded, DBSIZE 3
redis:8 -> redis:7-alpine REDIS0015 FAILED: 12:24:23.740 # Can't handle RDB format version 15
redis:7.2 -> valkey/valkey:9 REDIS0011 loaded, DBSIZE 3
redis:7-alpine -> valkey/valkey:9 REDIS0012 FAILED: 12:24:35.101 # Can't handle RDB format version 12
redis:8 -> valkey/valkey:9 REDIS0015 FAILED: 12:24:40.929 # Can't handle RDB format version 15
valkey/valkey:9 -> redis:8 VALKEY080 FAILED: 12:24:46.628 # Wrong signature trying to load DB from file
valkey/valkey:9 -> redis:7.2 VALKEY080 FAILED: 12:24:52.262 # Wrong signature trying to load DB from file
Yalnız üç yol açık: eski Redis'ten yeni Redis'e ve Redis 7.2'den Valkey 9'a. Dosyanın ilk 9 byte'ı formatı söylüyor: Redis 7.2 REDIS0011, 7.4 (redis:7-alpine, 7.4.12) REDIS0012, 8.10.3 REDIS0015 yazıyor; Valkey 9 ise artık kendi imzasıyla VALKEY080. Yükseltme tek yönlü: Redis 8'in yazdığı dosyayı 7.4 açamıyor, yani "sorun çıkarsa eski sürüme dönerim" planı RDB üzerinden çalışmıyor. Redis ile Valkey'in ortak noktası 7.2; ondan sonrası iki ayrı yol. Serinin bu son yazısında bu iki yolu anlatıyoruz: Redis 7'den 8.10'a sürüm sürüm neler geldi, Valkey 9 nerede ayrışıyor ve bu yazının ölçümüyle çıkan uyumluluk tablosu, StackExchange.Redis 2'den 3'e geçiş ve bir sürüm yükseltme planı.
Redis 7'den 8.10'a: Sürüm Sürüm
Aşağıdaki tablo yalnız Redis'in resmî sürüm notlarındaki ana başlıklardan ve bu seride kullandığımız özelliklerden derlendi; komutların since değerleri 8.10.3'te COMMAND DOCS ile doğrulandı.
| Sürüm (GA) | Öne çıkanlar | Seride |
|---|---|---|
| 7.4 (2024) | Hash field expiration (HEXPIRE, HTTL); RSALv2/SSPLv1 lisansına geçiş | 04 |
| 8.0 (Mayıs 2025) | JSON, Query Engine, time series ve probabilistic yapılar çekirdek dağıtımda; vector set (beta); HGETEX, HSETEX, HGETDEL; AGPLv3 seçeneği | 04, 07, 11 |
| 8.2 (Ağustos 2025) | XDELEX, XACKDEL; yeni BITOP operator'leri; CLUSTER SLOT-STATS | 10 |
| 8.4 (Kasım 2025) | SET … IFEQ, DELEX, DIGEST, MSETEX; XREADGROUP … CLAIM; atomic slot migration; FT.HYBRID | 03, 10, 13 |
| 8.6 (Şubat 2026) | XADD … IDMP; allkeys-lrm/volatile-lrm; HOTKEYS; hash ve sorted set bellek azaltımı | 06, 10, 12 |
| 8.8 (Mayıs 2026) | Array tipi; INCREX; XNACK; AGGREGATE COUNT; hash field seviyesinde keyspace notification | 06, 07, 08, 09, 10 |
| 8.10 (Temmuz 2026) | Compact hash ve HIMPORT; LMOVEM; SUNIONCARD, SDIFFCARD; BACKUP; XREADGROUP … MAXCOUNT/MAXSIZE; JSONPath genişletmeleri | 04, 05, 10, 11, 12 |
Altı ayda bir ara sürüm çıkıyor ve her biri birkaç komut ekliyor; bu seride kullandığımız komutların önemli bir kısmı 8.0 sonrasına ait. Bunun pratik anlamı: managed bir servis ya da şirketin onayladığı image birkaç ara sürüm geride kalırsa yazı yazı anlattığımız şeylerin bir kısmı orada yok. StackExchange.Redis bu komutlar için tipli method'lar sunsa da (3.3.0'ın notları 8.10 binding'lerini preview'dan çıkardı), sunucu eskiyse komut çalışma anında ERR unknown command ya da syntax hatası verir; paket sunucunun sürümünü senin yerine kontrol etmiyor.
8.12 şu an RC (Release Candidate; sürüm adayı) aşamasında: 29 Ekim'de ilk, 12 Kasım'da üçüncü aday çıktı. İlk adayın notları set member'larına ayrı ayrı süre veren komutları (SEXPIRE, STTL ve benzerleri) ve Redis'in çekirdeğine alınan sıkıştırılmış bitmap'leri sayıyor. GA çıkmadan production planına koyma; RC'ler dokümanda da production için uygun değil diye işaretli.
Ölçümle Uyumluluk Tablosu
Valkey, Redis 7.2.4'ten ayrıldı ve INFO'da hâlâ redis_version:7.2.4 yazıyor (02'de gördük); bu yüzden "Redis sürümü 7.2" diye karar veren bir araç Valkey 9'u da öyle görür. Hangi komutun nerede olduğunu dokümanlardan değil sunuculardan sordum: compat komutu her komut için iki sunucuya COMMAND DOCS gönderiyor ve since alanını yazıyor (-: sunucu komutu tanımıyor); seçenekler için komutu çalıştırıyor:
dotnet run --project src/Bookstore.RedisLab -- compat
command Redis 8.10.3 Valkey 9.1.3
HEXPIRE 7.4.0 9.0.0
HGETEX 8.0.0 9.0.0
HSETEX 8.0.0 9.0.0
HGETDEL 8.0.0 9.1.0
VADD 8.0.0 -
JSON.SET 1.0.0 -
FT.SEARCH 1.0.0 -
BF.ADD 1.0.0 -
XACKDEL 8.2.0 -
DELEX 8.4.0 -
DIGEST 8.4.0 -
MSETEX 8.4.0 9.1.0
HOTKEYS 8.6.0 -
XCFGSET 8.6.0 -
INCREX 8.8.0 -
XNACK 8.8.0 -
ARSET 8.8.0 -
HIMPORT 8.10.0 -
LMOVEM 8.10.0 -
SUNIONCARD 8.10.0 -
SDIFFCARD 8.10.0 -
BACKUP 8.10.0 -
DELIFEQ - 9.0.0
COMMANDLOG - 8.1.0
SET ... IFEQ ok ok
XADD ... IDMP ok ERR Invalid
ZUNIONSTORE ... AGGREGATE COUNT ok syntax error
Okurken iki şeye dikkat: JSON.SET, FT.SEARCH ve BF.ADD için görünen 1.0.0 modülün kendi sürüm numarası; bu modüller Redis 8.0 ile çekirdek dağıtıma girdi. Valkey'de ise ayrı valkey-bundle image'ında geliyorlar ve 11'de gördüğümüz gibi davranışları farklı. İkinci olarak bazı ortak özellikler farklı zamanda gelmiş: hash field expiration Redis'te 7.4'te, Valkey'de 9.0'da. Seri boyunca ölçtüğümüz farkların özeti: string compare-and-set'te Valkey'de SET … IFEQ ve DELIFEQ var, DELEX/DIGEST yok (03); stream'lerde CLAIM, IDMP ve XNACK yok (10); probabilistic yapılar, JSON ve arama ayrı modüller (07, 11); ACL'de (kullanıcı bazında komut izinleri) @json gibi modül kategorileri yok (14); BACKUP, HOTKEYS ve allkeys-lrm yok (12).
Valkey'in Kendi Yolu
Ayrışma tek yönlü değil: Valkey'in Redis'te olmayan özellikleri de var. Tablodaki DELIFEQ ve COMMANDLOG (yavaş komutların yanında büyük istek ve cevapları da kaydeden bir log) bunlardan iki tanesi. 13'te Valkey 9'un atomic slot migration'ını CLUSTER MIGRATESLOTS ile kaynak node'da çalıştırdık; Redis'in CLUSTER MIGRATION IMPORT'u ise hedef node'da çalışıyor: aynı fikir, farklı komut. Valkey 9'da cluster'da birden çok database de var, ama yalnız cluster-databases başlangıçta artırılırsa. Dosya formatı da ayrıldı: Valkey 9'un RDB'si VALKEY080 imzası taşıyor ve Redis onu "wrong signature" ile reddediyor. Valkey'in bir sonraki sürümü 9.2 şu an RC aşamasında.
Seçim için pratik bir bakış: Redis 8'in komutlarını (özellikle 8.4 sonrası string, stream ve hash eklemelerini) ya da çekirdekteki JSON/Query Engine'i kullanıyorsan Valkey'e geçiş kod değişikliği demek. Lisansın (01'de anlattığımız RSALv2/SSPLv1/AGPLv3 seçenekleri ile Valkey'in BSD (kaynak kodun serbestçe kullanılmasına izin veren açık kaynak lisansı) lisansı) ya da managed servisin (ElastiCache'in Valkey'e yönelmesi, Azure Managed Redis) belirleyici olduğu yerde ise uygulamanın kullandığı komut listesini bu yazıdaki gibi iki sunucuya sorarak çıkarmak tartışmayı kısaltır.
StackExchange.Redis 2'den 3'e
StackExchange.Redis 3.0.0 Haziran 2026'da çıktı ve sürüm notları artık GitHub'da (paketin GitHub organizasyonu da seredis olarak değişti). 2.x'ten geçerken kontrol edilecekler, release notlarından:
- 3.0.0: IO (ağ okuma/yazma) katmanı yeniden yazıldı, public API 2.13.17 ile aynı; varsayılan protokol RESP3 (Redis Serialization Protocol 3; pub/sub mesajlarını ve ek bilgileri aynı bağlantıda taşıyabilen sürüm). Tek bilinçli davranış değişikliği:
Execute[Async]artık admin komutlarını tanıyor;allowAdminaçık değilseFLUSHALLclient'ta reddediliyor (02'deKEYS, 12'deINFOiçin gördük). - 3.1.0: client tarafında coğrafi failover; 3.0'da kaldırılacağı söylenen eski API'ler uyarıdan derleme hatasına çevrildi.
- 3.2.0: .NET 6 hedefi kaldırıldı (.NET Standard üzerinden çalışıyor, Unix domain socket desteği hariç); cluster topology'si
CLUSTER SLOTS'tan okunuyor. - 3.4.0: RESP3'te pub/sub için yine ayrı bağlantı varsayılan (09'da 40 MB'lık cevabın paylaşılan bağlantıyı kopardığını gördük); cluster failover'dan daha hızlı toparlanma.
Derleme hatalarını görmek için 2.x döneminden tanıdık birkaç satırı 3.4.35'e karşı derledim:
Console.WriteLine(server.IsSlave);
Console.WriteLine(CommandFlags.PreferSlave);
mux.PreserveAsyncOrder = false;
await server.SlaveOfAsync(null);
Console.WriteLine(ConfigurationOptions.Parse("localhost").ResponseTimeout);
Program.cs(5,19): error CS0619: 'IServer.IsSlave' is obsolete: 'Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use IsReplica instead, this will be removed in 4.0.'
Program.cs(6,19): error CS0619: 'CommandFlags.PreferSlave' is obsolete: 'Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use PreferReplica instead, this will be removed in 4.0.'
Program.cs(7,1): error CS0619: 'ConnectionMultiplexer.PreserveAsyncOrder' is obsolete: 'Not supported; if you require ordered pub/sub, please see ChannelMessageQueue, will be removed in 4.0'
Program.cs(8,7): error CS0619: 'IServer.SlaveOfAsync(EndPoint, CommandFlags)' is obsolete: 'Starting with Redis version 5, Redis has moved to 'replica' terminology. Please use ReplicaOfAsync instead, this will be removed in 4.0.'
Program.cs(9,19): error CS0619: 'ConfigurationOptions.ResponseTimeout' is obsolete: 'This setting no longer has any effect, and should not be used - will be removed in 4.0.'
3.1.0'ın notu bu API'lerin "3.2'de" kaldırılacağını söylüyor; 3.4.35'teki mesajlar ise "4.0" diyor. Hata mesajlarının hepsi yerine konacak API'yi söylüyor: IsReplica, PreferReplica, ReplicaOfAsync, sıralı pub/sub için 09'daki ChannelMessageQueue. Bunlara ek olarak 3.x'in analyzer'ları derleme sırasında uyarı veriyor: 02'deki sync-over-async için SER307, 08'deki transaction task'ını erken await etmek için SER305. Geçişte bu uyarıları susturma, düzelt. 4.0 şu an NuGet'te alpha sürümlerde.
Bir Sürüm Yükseltme Planı
RDB dosyası tek yönlü olduğuna göre güvenli yol replication: yeni sürümü eski primary'nin replica'sı olarak başlat, senkronize olsun, sonra yeni sürümü primary yap. lab/upgrade/repl-compat.sh bunu dört kombinasyonda denedi:
redis:7-alpine -> redis:8 master_link_status:up, GET=42
redis:7.2 -> valkey/valkey:9 master_link_status:up, GET=42
redis:8 -> valkey/valkey:9 master_link_status:down, GET=nil 12:26:22.572 # Failed to load RDB
redis:8 -> redis:7-alpine master_link_status:down, GET=nil 12:26:34.329 # Failed trying to load the MASTER synchronization DB from disk, check server logs.
Replication da ilk senkronizasyonda bir RDB gönderdiği için RDB tablosuyla aynı sonucu verdi: Redis 7.4 → 8 ve Redis 7.2 → Valkey 9 çalışıyor, Redis 8 → Valkey 9 ve geriye doğru Redis 8 → 7.4 çalışmıyor. Redis 8'den Valkey'e geçmek isteyen biri için dosya ya da replication yolu yok; veriyi uygulama seviyesinde (key key okuyup yazarak) taşımak gerekiyor. Lab'daki script'ler Linux container'larında çalışıyor; Windows'ta Git Bash ya da WSL (Windows'ta Linux dağıtımı çalıştıran alt sistem) ile sh komutuyla çalıştırılabilir.
Plan, sırasıyla: kullandığın komutları hedef sürümde dene (compat gibi bir liste ve Testcontainers testleri, 14); hedef sürümün release notlarında config varsayılanı değişikliği ve "Known bugs and limitations" bölümüne bak; StackExchange.Redis'i sunucudan ayrı bir adımda ve önce güncelle, iki değişikliğin etkisi birbirine karışmasın; Functions kütüphanesini ve ACL kurallarını (yeni komut kategorileri) gözden geçir; staging'de replica ile yükselt; production'da yeni sürümü replica olarak ekle, master_link_status:up ve replication lag'i izle, failover ile primary yap (13'te gördüğümüz failover süresini planla); eski node'u bir süre replica olarak tutma, çünkü yeni primary'nin RDB'sini okuyamaz. Geri dönüş yolu eski sürümün yedeği ve o yedekten sonraki yazmaları kabul etmek; bunu yükseltmeden önce yaz.
Üretimde Dikkat
Patch sürümlerini (8.10.1 → 8.10.3 gibi) ara sürümlerden ayrı düşün: patch'ler güvenlik ve hata düzeltmesi, RDB formatını değiştirmiyor ve hızlı uygulanmalı (14). Ara sürümler (8.8 → 8.10) yeni komut ve config getiriyor; uygulama ekibiyle planlanmalı. Managed servis kullanıyorsan servisin hangi Redis ya da Valkey sürümünü çalıştırdığını INFO server ile değil servisin dokümanından doğrula; Valkey'in redis_version:7.2.4 raporu ve Azure Managed Redis'in Redis Enterprise tabanı bu bilgiyi yanıltıcı yapabiliyor. Image etiketini redis:8 gibi kayan bir etiket yerine redis:8.10.3 gibi tam sürümle sabitle; bu seride lab'da kayan etiket kullandık, testlerde (14) tam sürüm.
Sık Düşülen Tuzaklar
Yükseltmeden sonra eski sürüme RDB ile dönebileceğini sanmak: Redis 8'in dosyasını 7.4 açamadı.
Redis 8 verisini Valkey'e dosya ya da replication ile taşımaya çalışmak: ikisi de reddedildi.
Valkey'in redis_version:7.2.4 raporuna göre özellik kararı vermek.
Modül komutlarının (JSON.*, FT.*, BF.*) her Redis uyumlu sunucuda olduğunu varsaymak.
StackExchange.Redis 3'e geçerken RESP3 varsayılanını ve Execute'un admin kontrolünü test etmemek.
RC sürümünü production'a almak.
Lab'da ve production'da kayan image etiketi kullanmak: bir gün redis:8 8.12'yi çeker.
Küçük Bir Deneme
★☆☆ compat komutunun listesine bu seride kullandığın başka komutları ekle (XAUTOCLAIM, FCALL, SSUBSCRIBE, GEOSEARCH) ve iki sunucuda çalıştır. Hangileri ortak?
★★☆ rdb-compat.sh'ye valkey/valkey:8 ile redis:7.2 çiftlerini ekle. Valkey 8'in yazdığı dosyanın imzası ne, Redis 7.2 açabiliyor mu?
★★★ Bookstore.Api ve Bookstore.Worker'ı Valkey 9.1.3'e karşı çalıştır (ConnectionStrings__Redis=localhost:6380) ve bütün endpoint'leri dene. Hangi endpoint'ler hata veriyor? Her biri için Valkey'de çalışan bir alternatif yaz ve uygulamayı sunucu türüne göre doğru yolu seçecek hâle getir.
Seri burada bitiyor. On beş yazıda Redis'i bir cache'ten öte, Bookstore'un sayaçlarını, sepetini, çok satanlarını, stok rezervasyonlarını, sipariş olaylarını ve katalog aramasını taşıyan bir veri yapısı sunucusu olarak kurduk; her adımda neyin ölçümle doğrulandığını, neyin dokümandan geldiğini ayrı tuttuk.