Redis string tipi bir bayt dizisi saklar: metin, serileştirilmiş bir nesne ya da ikili veri olabilir. SET bir anahtara string değer yazar, GET onu okur, INCR ise değeri tamsayı olarak yorumlayıp atomik biçimde bir artırır. Bu üç komut ve seçenekleri, önbellekten sayaçlara kadar Redis’in en sık kullanılan işlerinin temelidir; bir string değer en fazla 512 MB olabilir.
Bu yazıda SET seçeneklerini (NX, XX, EX, PX, KEEPTTL, GET), Redis 8.4 ile gelen karşılaştırmalı yazmayı, MSET ve MGET ile toplu işlemleri, sayaç komutlarını ve APPEND, GETRANGE, SETRANGE, STRLEN, GETDEL, GETEX komutlarını resmî belgedeki örneklerle anlatıyoruz. Serinin tamamı için Redis öğrenme rehberine bakabilirsiniz.
SET ve GET: temel yazma ve okuma
Redis anahtarları da string olduğu için string tipindeki bir değer kullandığınızda aslında bir stringi başka bir stringe eşlemiş olursunuz. Belge bu tipin HTML parçalarını veya sayfalarını önbelleğe almak gibi işler için uygun olduğunu belirtir:
> SET bike:1 Deimos
OK
> GET bike:1
"Deimos"SET bir atamadır: anahtar zaten varsa eski değerin tipi ne olursa olsun üzerine yazar. Örneğin bir listeyi taşıyan anahtara SET yaparsanız liste kaybolur ve yerine string gelir. Ayrıca başarılı bir SET, anahtarın önceki yaşam süresini (TTL) siler; süreli bir anahtarın değerini güncellerken bunu unutmak yaygın bir hatadır. Süreyi korumak için aşağıda anlatılan KEEPTTL seçeneği vardır.
GET anahtar yoksa boş yanıt (nil) döndürür. Anahtar varsa ama string dışında bir tip taşıyorsa hata verir, çünkü GET yalnızca string değerlerle çalışır. Resmî hata sayfasındaki örnekte bir liste GET ile okunmaya çalışılıyor:
> RPUSH mylist "a"
(integer) 1
> GET mylist
(error) WRONGTYPE Operation against a key holding the wrong kind of valueSET seçenekleri: NX, XX, EX, PX, KEEPTTL ve GET

SET komutu davranışını değiştiren seçenekler alır. Koşul seçenekleri birbirini dışlar: NX anahtarı yalnızca henüz yoksa yazar, XX yalnızca zaten varsa yazar. Belgedeki örnekte anahtar zaten var olduğu için NX ile yazma yapılmaz ve boş yanıt döner, XX ile yazma başarılı olur:
> SET urun:1 Deimos
OK
> SET urun:1 bike NX
(nil)
> SET urun:1 bike XX
OKSüre seçenekleri de birbirini dışlar. EX saniye, PX milisaniye cinsinden bir yaşam süresi verir; EXAT ve PXAT ise anahtarın sona ereceği Unix zamanını saniye veya milisaniye olarak alır. Hepsi pozitif tamsayı ister. KEEPTTL, anahtarın mevcut yaşam süresini korur. Belgedeki örnekte bir anahtar bir dakikalık süreyle yazılır:
> SET anotherkey "will expire in a minute" EX 60
OKGET seçeneği ise yazmadan önceki değeri döndürür; anahtar yoksa boş yanıt verir. Anahtardaki değer string değilse hata döner ve SET iptal edilir. Bu seçenek, eski GETSET komutunun yaptığı işi SET içinde yapmanızı sağlar. Belge, SET seçenekleri SETNX, SETEX, PSETEX ve GETSET komutlarının yerini tutabildiği için bu komutların ileride kullanımdan kaldırılabileceğini not eder; yeni kodda SET seçeneklerini tercih edin.
| Seçenek | Anlamı | Birlikte kullanılamaz |
|---|---|---|
| NX | Yalnızca anahtar yoksa yaz | XX ve IF* koşulları |
| XX | Yalnızca anahtar varsa yaz | NX ve IF* koşulları |
| EX saniye / PX milisaniye | Göreli yaşam süresi ver | Diğer süre seçenekleri |
| EXAT / PXAT | Mutlak Unix zamanında sona erdir | Diğer süre seçenekleri |
| KEEPTTL | Mevcut süreyi koru | Diğer süre seçenekleri |
| GET | Önceki değeri döndür | Yok |
Yanıt türünü doğru okumak önemlidir. GET seçeneği yoksa başarılı yazmada OK, koşul sağlanmadığı için yazma yapılmadığında boş yanıt döner. GET seçeneği varsa yanıt, yazma yapılsın yapılmasın önceki değerdir; anahtar önceden yoksa boş yanıttır. Yani GET ile birlikte NX kullanıyorsanız yazmanın gerçekleşip gerçekleşmediğini yanıttan değil, önceki değerin olup olmamasından çıkarırsınız. SET ... NX EX ile basit bir kilit kurmak mümkündür; belge bu desenin yerine Redlock algoritmasını önerir, ayrıntılar dağıtık kilit yazısında.
IFEQ ve DELEX: karşılaştırarak yaz, karşılaştırarak sil (Redis 8.4)
Redis 8.4 ile SET, yazmadan önce anahtarın mevcut değerini kontrol edebilir hale geldi. IFEQ seçeneğiyle SET yalnızca mevcut değer verdiğiniz değere eşitse başarılı olur. Böylece daha önce okuduğunuz bir değeri, arada başka bir istemcinin yaptığı değişikliği ezmeden güncelleyebilirsiniz; bu desene compare-and-swap (CAS) denir. DELEX komutu aynı kontrolü silme için yapar. Belgedeki örnek:
> SET urun:1 Deimos
OK
> SET urun:1 Ares IFEQ Deimos
OK
> SET urun:1 Zeus IFEQ Deimos
(nil)
> GET urun:1
"Ares"
> DELEX urun:1 IFEQ Deimos
(integer) 0
> DELEX urun:1 IFEQ Ares
(integer) 1İkinci SET başarısız olur çünkü değer artık Ares’tir; ilk DELEX de aynı nedenle 0 döndürür. IFNE kontrolü tersine çevirir. Bu iki seçenek arasında önemli bir fark vardır: anahtar yoksa IFEQ onu oluşturmaz, IFNE ise oluşturur. IFDEQ ve IFDNE seçenekleri değerin kendisi yerine XXH3 algoritmasıyla hesaplanan özetini karşılaştırır; büyük değerlerde bütün içeriği göndermek zorunda kalmazsınız. Özeti DIGEST komutu onaltılık string olarak verir:
> SET key1 "Hello world"
OK
> DIGEST key1
"b6acb9d84a38ff74"MSET, MGET ve MSETNX: birden fazla anahtar tek komutta

Birden fazla anahtarı tek komutla yazmak ve okumak, sunucuya gidip gelme sayısını azalttığı için gecikmeyi düşürür. MSET anahtar-değer çiftleri alır, MGET ise değerleri istediğiniz sırayla bir dizi olarak döndürür:
> MSET bike:1 "Deimos" bike:2 "Ares" bike:3 "Vanth"
OK
> MGET bike:1 bike:2 bike:3
1) "Deimos"
2) "Ares"
3) "Vanth"MSET atomiktir: bütün anahtarlar aynı anda yazılır ve başka bir istemci bazı anahtarların güncellenip diğerlerinin güncellenmediği bir ara durumu göremez. Komut her zaman OK döndürür, çünkü başarısız olamaz. MGET de hiç hata vermez: var olmayan ya da string olmayan her anahtar için ilgili konumda boş yanıt döner.
> SET key1 "Hello"
OK
> SET key2 "World"
OK
> MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)Var olan değerlerin üzerine yazmak istemiyorsanız MSETNX kullanılır. Bu komut anahtarlardan yalnızca biri bile varsa hiçbir şey yazmaz; ya hepsi ya hiçbiri yazılır. Bu sayede tek bir mantıksal nesnenin farklı alanlarını temsil eden anahtarları birlikte oluşturabilirsiniz:
redis> MSETNX key1 "Hello" key2 "there"
(integer) 1
redis> MSETNX key2 "new" key3 "world"
(integer) 0
redis> MGET key1 key2 key3
1) "Hello"
2) "there"
3) (nil)Redis 8.4 ile gelen MSETEX ise birden fazla anahtarı ortak bir süreyle tek atomik işlemde yazar. Sözdizimi önce anahtar sayısını (numkeys), sonra anahtar-değer çiftlerini, ardından isteğe bağlı NX veya XX koşulunu ve EX, PX, EXAT, PXAT, KEEPTTL süre seçeneklerinden birini alır. Burada NX “anahtarların hiçbiri yoksa”, XX “hepsi varsa” anlamına gelir. Komut hepsi yazıldığında 1, hiçbiri yazılmadığında 0 döndürür.
MSETEX 2 oturum:a deger1 oturum:b deger2 EX 300Cluster ortamında çok anahtarlı komutların davranışı farklıdır; anahtarların aynı hash slot’ta olması gerekir. Bunun için cluster ve hash slot yazısına bakın.
Sayaç olarak string: INCR, INCRBY, DECR, INCRBYFLOAT
Redis’in ayrı bir tamsayı tipi yoktur; sayaçlar string olarak saklanır. INCR stringi 64 bit işaretli bir onluk tamsayı olarak yorumlar, bir artırır ve sonucu yeni değer olarak yazar. Anahtar yoksa önce 0 kabul edilir. Belgeye göre tamsayı taşıyan stringler bellekte tamsayı gösterimiyle saklandığı için string gösteriminin ek bir maliyeti yoktur.
> SET total_crashes 0
OK
> INCR total_crashes
(integer) 1
> INCRBY total_crashes 10
(integer) 11INCRBY verilen miktar kadar artırır, DECR bir azaltır, DECRBY verilen miktar kadar azaltır. Belge bunların içeride aynı komutun biraz farklı davranan biçimleri olduğunu söyler. Asıl önemli özellik atomikliktir: birden fazla istemci aynı anahtara aynı anda INCR gönderse bile yarış durumu oluşmaz. İki istemcinin aynı anda 10 okuyup ikisinin de 11 yazması gibi bir durum yaşanmaz; son değer her zaman 12 olur, çünkü okuma, artırma ve yazma adımları başka hiçbir komut çalışmazken yapılır.
Değer tamsayı olarak yorumlanamıyorsa hata döner. Resmî hata sayfası iki örnek verir: metin taşıyan bir anahtarı artırmak ve sayı beklenen yere metin yazmak.
> SET counter "abc"
OK
> INCR counter
(error) ERR value is not an integer or out of range1.5 gibi ondalıklı bir değer de aynı hatayı verir. Sınır 9223372036854775807’dir; bir artırma bu değeri aşacaksa hata ERR increment or decrement would overflow olur. Ondalıklı sayılar için INCRBYFLOAT vardır; negatif bir artış değeriyle azaltma da yapar ve sonucu string olarak döndürür:
redis> SET mykey 10.50
OK
redis> INCRBYFLOAT mykey 0.1
"10.6"
redis> INCRBYFLOAT mykey -5
"5.6"
redis> SET mykey 5.0e3
OK
redis> INCRBYFLOAT mykey 2.0e2
"5200"Örnekte görüldüğü gibi üstel gösterimle verilen değerler de kabul edilir ama sonuç her zaman tamsayı kısmı, gerekirse nokta ve ondalık basamaklar biçiminde saklanır; sondaki sıfırlar atılır. INCRBYFLOAT çoğaltma bağlantısına ve AOF dosyasına bir SET olarak yazılır; böylece farklı makinelerdeki kayan nokta farkları tutarsızlığa yol açmaz.
Sayaçların tipik kullanımı, her olayda bir anahtarı artırmaktır; örneğin kullanıcı kimliği ile tarihi birleştiren bir anahtarla günlük sayfa görüntüleme sayısı. Sayacı okuyup sıfırlamak için belge GETSET mycounter "0" desenini gösterir; bugün aynı işi SET komutunun GET seçeneğiyle yapabilirsiniz. INCR ile EXPIRE birlikte kullanılarak kurulan hız sınırlama desenleri için API rate limiting stratejileri, sayaca süre vermenin kuralları için EXPIRE ve TTL yazısına bakın.
APPEND, STRLEN, GETRANGE ve SETRANGE: string üzerinde çalışmak
APPEND mevcut değerin sonuna ekleme yapar ve yeni uzunluğu döndürür; anahtar yoksa boş stringle oluşturur, yani ilk çağrıda SET gibi davranır. STRLEN değerin uzunluğunu verir; anahtar yoksa 0 döndürür, string olmayan bir değerde hata verir.
redis> EXISTS mykey
(integer) 0
redis> APPEND mykey "Hello"
(integer) 5
redis> APPEND mykey " World"
(integer) 11
redis> GET mykey
"Hello World"GETRANGE başlangıç ve bitiş konumları arasındaki alt stringi döndürür; iki konum da dahildir. Negatif konumlar sondan sayar: -1 son karakter, -2 sondan ikincidir. Aralık stringin dışına taşarsa sonuç gerçek uzunlukla sınırlanır, hata verilmez:
redis> SET mykey "This is a string"
OK
redis> GETRANGE mykey 0 3
"This"
redis> GETRANGE mykey -3 -1
"ing"
redis> GETRANGE mykey 0 -1
"This is a string"
redis> GETRANGE mykey 10 100
"string"SETRANGE verilen konumdan başlayarak stringin bir bölümünün üzerine yazar ve yeni uzunluğu döndürür. Konum mevcut uzunluktan büyükse aradaki boşluk sıfır baytlarla doldurulur; var olmayan anahtar boş string kabul edilir:
redis> SET key1 "Hello World"
OK
redis> SETRANGE key1 6 "Redis"
(integer) 11
redis> GET key1
"Hello Redis"
redis> SETRANGE key2 6 "Redis"
(integer) 11
redis> GET key2
"\x00\x00\x00\x00\x00\x00Redis"GETDEL ve GETEX: okurken sil, okurken süre ver
GETDEL değeri okur ve anahtarı siler; silme yalnızca değer string ise yapılır. Anahtar yoksa ya da string değilse boş yanıt döner. Tek kullanımlık kodlar gibi bir kez okunması gereken değerler için uygundur:
redis> SET mykey "Hello"
OK
redis> GETDEL mykey
"Hello"
redis> GET mykey
(nil)GETEX değeri okur ve isteğe bağlı olarak süresini değiştirir. GET gibi görünse de bir yazma komutudur. EX, PX, EXAT, PXAT seçenekleri süre verir, PERSIST mevcut süreyi kaldırır; bu seçenekler birbirini dışlar. Belgedeki örnekte önce süresiz okunur, sonra okuma sırasında 60 saniyelik süre verilir:
redis> SET mykey "Hello"
OK
redis> GETEX mykey
"Hello"
redis> TTL mykey
(integer) -1
redis> GETEX mykey EX 60
"Hello"
redis> TTL mykey
(integer) 60Her okumada süresi uzayan oturum anahtarları gibi “kayan süre” desenleri için GETEX tek komutluk bir çözümdür.
Ne zaman string, ne zaman başka bir tip?
Belge, yapılandırılmış veriyi serileştirilmiş bir string olarak saklıyorsanız hash veya JSON tiplerini de düşünmenizi önerir. Bir nesnenin tek bir alanını sık sık değiştiriyorsanız bütün stringi okuyup yeniden yazmak yerine hash komutları ile yalnızca o alanı güncellemek daha verimlidir; iç içe yapılar için JSON komutları vardır. Bit düzeyinde işlemler ve tek string içinde çok sayıda tamsayı sayaç için bitmap ve bitfield yazısına bakın.
Sık yapılan hatalar

- SET ile süreyi kaybetmek: Başarılı
SETönceki TTL’yi siler. Süreyi korumak içinKEEPTTLekleyin. - Başka tipteki anahtarı ezmek:
SETtip kontrolü yapmaz; bir liste veya hash’in üzerine yazabilir. - Ondalıklı sayıya INCR uygulamak:
INCRyalnızca tamsayılarla çalışır; ondalık içinINCRBYFLOATkullanın. - Oku-artır-yaz döngüsünü istemcide yapmak:
GETsonraSETyarış durumuna açıktır;INCRatomiktir. - MGET sonucunda hata beklemek: String olmayan anahtarlar hata yerine boş yanıt döndürür; boş yanıtı “yok” sanmayın, tipini kontrol edin.
- IFEQ’i eski sunucuda denemek: Bu seçenekler Redis 8.4 gerektirir.
Sık Sorulan Sorular
Bir Redis stringi en fazla ne kadar büyük olabilir?
Varsayılan olarak 512 MB. Bu nedenle SETRANGE için en büyük konum 536870911’dir.
SETNX ve SETEX hâlâ kullanılabilir mi?
Evet, çalışıyorlar. Ancak belge, SET seçenekleri bu komutların yerini tuttuğu için ileride kullanımdan kaldırılabileceklerini belirtir. SET key value NX ve SET key value EX saniye biçimini tercih edin.
INCR neden yarış durumu oluşturmaz?
Redis okuma, artırma ve yazma adımlarını tek bir komut olarak, başka hiçbir istemcinin komutu çalışmıyorken yapar. Bu yüzden aynı anahtara eşzamanlı gelen artırmaların hiçbiri kaybolmaz.
Var olmayan bir anahtara INCR yaparsam ne olur?
Anahtar önce 0 kabul edilir, sonra artırılır; yanıt 1 olur ve anahtar oluşturulmuş olur.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Redis öğrenme rehberi · EXPIRE ve TTL · Anahtar isimlendirme · Bitmap ve bitfield · API rate limiting