Redis kaynak kodu öğreniminin Redis işlemi

Bir bellek veritabanı olarak, geleneksel veritabanlarının işlem özelliklerini de destekler. Bu makale, Redis'teki işlemlerin uygulama ilkesini kaynak kodu perspektifinden analiz edecektir.

Ne

Redis işlemi, birden çok komut isteğini paketlemek ve ardından birden çok komutu aynı anda ve sırayla yürütmek için bir mekanizma sağlar ve işlemin yürütülmesi sırasında, sunucu işlemi kesintiye uğratmaz ve işlemde olmayan diğer komut isteklerini yürütmez. Diğer komutları çalıştırmadan önce işlemdeki tüm komutları çalıştıracaktır.

Nasıl

Redis, işlem işlevlerini uygulamak için multi, discard, exec, watch ve unwatch gibi komutlar sağlar.

Redis işlemleri çoklu komutla başlar, ardından işlemde yürütülecek komutlar ve son olarak exec komutu veya atma komutu gelir. İşleme eklenen tüm komutlar atomik olarak yürütülecek ve işleme eklenmeyen diğer komutlar arasına eklenmeyecektir.

multi, exec ve at

Çoklu komut Redis istemcisine bir şeyi başlatmasını söyler ve ardından Redis bir Tamam döndürür. Sonraki tüm komutlar Redis hemen çalıştırılmaz, yalnızca QUEUED sonucu döndürülür ve exec komutuyla karşılaşılana kadar önceki tüm komutlar çalıştırılmaz. , Veya atma komutuyla karşılaşılırsa, işleme yürütülmeden önce eklenen komut atılacaktır.

127.0.0.1:6379 > isim al

(sıfır)

127.0.0.1:6379 > cinsiyet al

(sıfır)

127.0.0.1:6379 > çok

tamam

127.0.0.1:6379 > Slogen adını ayarla

KUYRUKLU

127.0.0.1:6379 > cinsiyetini ayarla erkek

KUYRUKLU

127.0.0.1:6379 > exec

1) Tamam

2) Tamam

127.0.0.1:6379 > mget adı cinsiyet

1) "Slogen"

2) "erkek"

izlemek

Watch komutu, Redis tarafından sağlanan iyimser bir kilittir. Yürütme yürütülmeden önce herhangi bir sayıda veritabanı anahtarını izleyebilir ve exec komutu yürütüldüğünde, izlenen anahtarlardan en az birinin değiştirilip değiştirilmediğini kontrol edin. Eğer öyleyse, sunucu İşlemi gerçekleştirmeyi reddedin ve müşteriye işlemin yürütülmesinin başarısızlığını temsil eden boş bir yanıt verin.

Önce client1 üzerinde aşağıdaki komutları yürütün:

127.0.0.1:6379 > isim al

(sıfır)

127.0.0.1:6379 > izle adı

tamam

127.0.0.1:6379 > çok

tamam

127.0.0.1:6379 > set adı slogen

KUYRUKLU

127.0.0.1:6379 > cinsiyetini ayarla erkek

KUYRUKLU

127.0.0.1:6379 > isim al

KUYRUKLU

Şu anda, istemci exec komutunu yürütmedi ve ardından adı değiştirmek için client2 altında aşağıdaki komutu çalıştırdı:

127.0.0.1:6379 > isim ayarla rio

tamam

127.0.0.1:6379 > isim al

"rio"

Sonra client1 altında exec komutunu yürütün:

127.0.0.1:6379 > exec

(sıfır)

127.0.0.1:6379 > isim al

"rio"

Yürütme sonucundan, exec komutu istemci1'de yürütüldüğünde, Redis'in ad alanının diğer istemciler tarafından değiştirildiğini algılayacağı, bu nedenle işlemdeki tüm komutları yürütmeyi reddettiği ve yürütme hatasını belirtmek için doğrudan sıfır döndürdüğü görülebilir. Şu anda elde edilen adın değeri hala client2'deki rio setidir.

Neden

çok

Redis'in işlemi çoklu komutla başlar, bu nedenle analizi çoklu komutun kaynak kodundan başlatın.

Redis, istemci tarafından gönderilen komutu aldığında, multi.c dosyasında bulunan multiCommand () yöntemini çalıştıracaktır.

void multiCommand (istemci * c) {

// 1. Bayrakların zaten CLIENT_MULTI içerdiği tespit edilirse

// İlgili istemcinin zaten işlem bağlamında olduğunu ve bir hata döndürdüğünü gösterir

eğer (c- > bayraklar ve CLIENT_MULTI) {

addReplyError (c, "MULTI çağrıları yuvalanamaz");

dönüş;

}

// 2. CLIENT_MULTI bayrak logosunu açın

c- > bayraklar | = MÜŞTERİ_ÇOKLU;

// 3. Müşteriye işlemin başarıyla açıldığını bildirmek için ok döndür

addReply (c, shared.ok);

}

Kaynak kodundan da görebileceğiniz gibi, multiCommand () esas olarak aşağıdaki üç şeyi gerçekleştirir:

Çoklu komutu gönderen istemcinin zaten bir işlemde olup olmadığını kontrol edin ve öyleyse, doğrudan bir hata verin. Buradan da görebileceğiniz gibi Redis, iç içe işlem yürütmeyi desteklemez.

İşlemi girdiğini belirtmek için ilgili istemcinin bayraklarına MULTI_CLIENT bayrağını ekleyin.

OK döndürmek istemciye işlemin başarıyla açıldığını bildirir.

Önceki makaleden de görebileceğiniz gibi, Redis İstemci tarafından gönderilen tüm komutları aldıktan sonra, işlemi processCommand () yönteminde çalıştıracaktır. ProcessCommand () 'de, kodun aşağıdaki bölümü vardır:

ProcessCommand () gerçek komutu yürütmeden önce, önce karşılık gelen istemcinin zaten işlem bağlamında olup olmadığını belirleyecektir.Eğer öyleyse ve yürütülmesi gereken komut exec, discard, multi ve watch gibi dört komuttan herhangi biri değildir, sonra Yürütülecek komutu kuyruğa eklemek için queueMultiCommand () yöntemini çağırın, aksi takdirde komutu doğrudan yürütmek için call () öğesini çağırın.

queueMultiCommand ()

Redis, işleme eklenen komutları aşağıdaki gibi uygulanan Redis kuyruğuna eklemek için queueMultiCommand () yöntemini çağırır:

QueueMultiCommand () yöntemi, esas olarak işleme eklenecek komutu multiCmd yapısının değişkeninde kapsüllemek ve ardından istemciye yerleştirmektir. > Mstate.commands dizisinde multiCmd'nin tanımı aşağıdaki gibidir:

typedef struct multiCmd {

robj ** argv; // komut parametresi dizisi

int argc; // Komutun parametre sayısı

struct redisCommand * cmd; // çalıştırılacak komut

} multiCmd;

Ve mstate alanı şu şekilde tanımlanır:

typedef struct client {

// Diğer ihmal edilen kodlar

multiState mstate; / * MULTI / EXEC durumu * /

} müşteri;

MultiState'in yapısı:

typedef struct multiState {

multiCmd * komutları; / * MULTI komut dizisi * /

int count; / * Toplam MULTI komut sayısı * /

int minreplicas; / * zaman uyumlu çoğaltma için MINREPLICAS * /

time_t minreplicas_timeout; / * Unixtime olarak MINREPLICAS zaman aşımı. * /

} multiState;

komutlar: işlemde yürütülecek tüm komutları depolayan multiCmd türü bir dizi

count: geçerli işlemde depolanan tüm komutların sayısı

Diğer iki alan mevcut sürümde (3.2.28) kullanılmamaktadır.

İki komut setinin slogen ve lpush num 20 adının mevcut işlem kuyruğunda zaten mevcut olduğunu varsayarsak, istemcideki mstate verileri aşağıdaki gibidir:

Şu anda işleme get name komutu eklendiğinde yapı diyagramı aşağıdaki gibidir:

Yanlış komut: CLIENT_DIRTY_EXEC

Sonra bir soru var mesela işleme eklediğim komut var olmayan bir komut veya komut parametresi gibi komutun nasıl kullanıldığı gibi bu komut işleme şu anda eklenecek mi?

Daha önce belirtildiği gibi, Redis tarafından alınan tüm komutlar processCommand () yönteminde yürütülür. İlgili komut fiilen yürütülmeden önce processCommand () yöntemi, yürütülecek komut üzerinde bir dizi kontrol gerçekleştirir. Kod aşağıdaki gibidir:

Yukarıdaki koddan görülebileceği gibi, processCommand (), flagTransaction () işlevini çağıracak ve kontrollerden herhangi biri başarısız olursa yürütülecek komutla ilgili bir dizi kontrol sırasında ilgili bilgileri istemciye döndürecektir. FlagTransaction () uygulaması aşağıdaki gibidir. :

void flagTransaction (müşteri * c) {

eğer (c- > bayraklar ve CLIENT_MULTI)

// Bayraklar CLIENT_MULTI bayrak bitini içeriyorsa, bu zaten işlem bağlamında olduğu anlamına gelir

// İlgili istemcinin bayrakları için CLIENT_DIRTY_EXEC bayrağını etkinleştirin

c- > bayraklar | = CLIENT_DIRTY_EXEC;

}

FlagTransaction () yöntemi, karşılık gelen istemcinin işlem bağlamında olup olmadığını tespit edecek ve öyleyse, ilgili istemcinin bayraklar alanı için CLIENT_DIRTY_EXEC bayrağını açacaktır.

Başka bir deyişle, komutun mevcut olmaması veya karşılık gelen komut parametresinin yanlış olması gibi çeşitli nedenlerle komut işleme eklenirse, ilgili komut mstate.commands dizisine eklenmeyecek ve aynı zamanda ilgili istemciye verilecektir. Bayraklar alanı CLIENT_DIRTY_EXEC bayrak bitini açar.

izle komutu

İstemci bir işlem bağlamında olduğunda, watch komutu hemen yürütülebilecek birkaç komuttan biridir. Watch komutuna karşılık gelen kod, aşağıdaki gibi uygulanan watchCommand () işlevidir:

void watchCommand (client * c) {

int j;

eğer (c- > bayraklar ve CLIENT_MULTI) {

// İzleme komutunu yürüten müşteri işlemin bağlamındaysa, doğrudan dön

addReplyError (c, "MULTI içinde WATCH'a izin verilmez");

dönüş;

}

için (j = 1; j < c- > argc; j ++)

// İzlemeye geçirilen her biri için watchForKey () 'i çağırabilirsiniz

watchForKey (c, c- > argv);

addReply (c, shared.ok);

}

WatchCommand () yöntemi ilk olarak, saati yürütme komutunun zaten işlem bağlamında olup olmadığını belirleyecek ve eğer öyleyse, bir hata bildirecek ve Redis işleminde watch komutunun çağrılamayacağını belirten bir geri dönecektir.

Daha sonra, watch komutu tarafından iletilen tüm anahtarlar için, sırasıyla aşağıdaki gibi tanımlanan watchForKey () yöntemini çağırın:

WatchForKey () yöntemi aşağıdaki işlemleri gerçekleştirir:

İlgili anahtarın istemcide zaten mevcut olup olmadığını belirleyin. > Watched_keys listesinde, zaten varsa, doğrudan dönün. müşteri > watched_keys, karşılık gelen istemci nesnesi için izlenecek tüm anahtarları tutar.

Mevcut değilse, müşteriye gidin- > db > Watched_keys'de bu anahtarı izleyen tüm istemci nesnelerini arayın. müşteri > db > watched_keys, bu anahtarı izleyen tüm istemcilerin bir listesini dikte yapısında kaydeder.

İkinci adımdaki liste mevcutsa, izleme komutunu yürüten istemciyi listenin sonuna ekleyin. Bu yoksa, henüz hiçbir istemcinin anahtarı izlemediği anlamına gelir, ardından yeni bir liste oluşturun ve istemciye ekleyin. > db > watched_keys ve ardından watch komutunu çalıştıran istemciyi yeni oluşturulan listenin sonuna ekleyin.

Aktarılan anahtarı bir watchedKey yapı değişkenine kapsülleyin ve istemciye ekleyin. > Watched_key listesinin sonu.

Mevcut müşteriyi varsayarsak ... > db > İzlenen anahtarların izleme durumu aşağıdaki şekilde gösterilmektedir:

Ve müşteri- > Watched_keys izleme aşağıdaki gibidir:

Şu anda, client_A, key1 key2 key3 komutunu çalıştırır. Komutu çalıştırdıktan sonra, client- > db > watched_keys sonucu:

Ve müşteri- > watched_keys sonucu:

Key1 için, şu anda hiçbir istemci key1'i izlemiyor, bu nedenle şu anda client_A yeni bir liste oluşturacak, kendisini bu listeye ekleyecek ve ardından istemciye eşleme ilişkisini ekleyecek- > db > watched_keys ve ardından key1 istemciye eklenecektir- > Watched_keys listesinin sonu.

Key2 için, zaten watched_keys listesinde mevcut olduğundan, herhangi bir işlem yapmadan doğrudan geri dönecektir.

Key3 için, çünkü müşteri- > db > Client_B ve client_C zaten onu watched_keys'de izliyor, bu nedenle client_A doğrudan izleme listesinin sonuna eklenecek ve ardından key3, client_A izleme listesine eklenecektir.

Verileri değiştirin: CLIENT_DIRTY_CAS

Watch komutunun işlevi, izlenen anahtarın işlem sırasında diğer istemciler tarafından değiştirilip değiştirilmediğini tespit etmektir.Eğer değiştirilmişse, işlemin yürütülmesini engelleyecektir.Bu işlev nasıl uygulanır?

Set komutunu analiz için örnek olarak alın.

Client_A'nın izleme adı komutunu yürüttüğünü ve ardından işlemi başlatmak için multi komutu yürüttüğünü ancak exec komutunu yürütmediğini varsayalım. Şu anda, client_B set adı slogen komutunu yürütür. Tüm süreç aşağıdaki gibidir:

T4'te, client_B, adı değiştirmek için set komutunu yürütür. Set komutunu aldıktan sonra, Redis, aşağıdaki gibi uygulanan setCommand yöntemini yürütür:

void setCommand (client * c) {

// Diğer ihmal edilen kodlar

setGenericCommand (c, bayraklar, c- > argv, c- > argv, expire, unit, NULL, NULL);

}

SetCommand () 'ın sonunda setGenericCommand () yöntemi çağrılır ve yöntem şu şekilde uygulanır:

void setGenericCommand (client * c, int flags, robj * key, robj * val, robj * expire, int unit, robj * ok_reply, robj * abort_reply) {

// Diğer ihmal edilen kodlar

setKey (c- > db, anahtar, val);

// Diğer ihmal edilen kodlar

}

SetGenericCommand () yönteminde setKey () yöntemi çağrılacak ve ardından setKey () yöntemine bakılacaktır:

void setKey (redisDb * db, robj * key, robj * val) {

if (lookupKeyWrite (db, key) == NULL) {

dbAdd (db, anahtar, val);

} Başka {

dbOverwrite (db, anahtar, val);

}

incrRefCount (val);

removeExpire (db, anahtar);

// Anahtarın değiştirildiğini bildirin

signalModifiedKey (db, anahtar);

}

SetKey () yönteminin sonunda, redis veritabanına verilerin değiştirildiğini bildirmek için signalModifiedKey () çağrılır. SignalModifiedKey () yöntemi aşağıdaki şekilde uygulanır:

void signalModifiedKey (redisDb * db, robj * key) {

touchWatchedKey (db, anahtar);

}

SignalModifiedKey () yönteminin touchWatchedKey () yöntemini çağırdığını görebilirsiniz, kod aşağıdaki gibidir:

void touchWatchedKey (redisDb * db, robj * key) {

müşteri listesi;

listIter li;

listNode * ln;

eğer (dictSize (db- > watched_keys) == 0) dönüş;

// 1. redisDb'den- > Watched_keys içinde ilgili müşteri listesini bulun

istemciler = dictFetchValue (db- > watched_keys, anahtar);

eğer (! müşteriler) dönerse;

/ * Bu anahtarı izleyen tüm istemcileri CLIENT_DIRTY_CAS olarak işaretle * /

/ * Bu anahtarı zaten izliyor muyuz kontrol edin * /

listRewind (müşteri, li);

while ((ln = listNext (li))) {

// 2. Müşteri listesini sırayla dolaşın ve her müşteriye işaretler alanını verin

// CLIENT_DIRTY_CAS bayrağını açın

istemci * c = listNodeValue (ln);

c- > bayraklar | = CLIENT_DIRTY_CAS;

}

}

TouchWatchedKey () yöntemi şu iki şeyi yapar:

RedisDb'den- > Watched_keys içinde bu anahtarı izleyen istemcilerin listesini bulun. Daha önce izleme komutunu analiz ederken belirtildiği gibi, eğer bir müşteri izleme tuşları komutunu çalıştırırsa, bu durumda redis, karşılık gelen (anahtar, müşteri) ilişkisini redisDb- anahtar-değer çiftleri biçiminde kaydedecektir. > Watched_key alanının içinde.

İlk adımda bulunan her bir istemci nesnesi için, CLIENT_DIRTY_CAS bayrak biti, bu istemcinin işaretler alanı için açılacaktır.

Redis'te, veritabanının içeriğini değiştiren tüm komutlar sonunda signalModifiedKey () yöntemini çağıracak ve signalModifiedKey () 'de, CLIENT_DIRTY_CAS bayrak biti bu anahtarı izleyen tüm istemcilere eklenecektir.

exec komutu

Exec komutu, işlemleri yürütmek için kullanılır ve karşılık gelen kod, aşağıdaki gibi uygulanan execCommand () yöntemidir:

void execCommand (client * c) {

int j;

robj ** orig_argv;

int orig_argc;

struct redisCommand * orig_cmd;

int must_propagate = 0; / * MULTI / EXEC'i AOF / slave'lere yaymanız mı gerekiyor? * /

// 1. İlgili müşterinin işleme ait olup olmadığını belirleyin

eğer (! (c- > bayraklar ve CLIENT_MULTI)) {

addReplyError (c, "MULTI'sız EXEC");

dönüş;

}

/ **

* 2. İşlemin gerçekleştirilmesi gerekip gerekmediğini kontrol edin, aşağıdaki iki durumda işlem gerçekleştirilmeyecektir

* 1) İzlenen anahtar, açılmakta olan CLIENT_DIRTY_CAS bayrağına karşılık gelen diğer istemciler tarafından değiştirildi

*, Bu sefer hiçbir işlem yapılmadığını gösteren bir sıfır döndürür

* 2) İşlem kuyruğuna, CLIENT_DIRTY_EXEC bayrağının açılmasına karşılık gelen bir komut eklendiğinde bir hata oluşur.

*, Bu sefer bir uygulama hatası döndürecektir

* /

eğer (c- > bayraklar ve (CLIENT_DIRTY_CAS | CLIENT_DIRTY_EXEC)) {

addReply (c, c- > bayraklar ve CLIENT_DIRTY_EXEC? shared.execaborterr:

shared.nullmultibulk);

// tüm işlemleri iptal et

işlemi iptal et (c);

goto handle_monitor;

}

/ * Sıraya alınan tüm komutları çalıştır * /

// 3. Bu müşteri tarafından izlenen tüm anahtarları izle

unwatchAllKeys (c); / * ASAP'yi Unwatch Unwatch Aksi takdirde CPU döngülerini boşa harcayacağız * /

orig_argv = c- > argv;

orig_argc = c- > argc;

orig_cmd = c- > cmd;

addReplyMultiBulkLen (c, c- > mstate.count);

// 4. İşlem kuyruğundaki tüm komutları sırayla çalıştır

için (j = 0; j < c- > mstate.count; j ++) {

c- > argc = c- > mstate.commands.argc;

c- > argv = c- > mstate.commands.argv;

c- > cmd = c- > mstate.commands.cmd;

/ * İlk yazma işlemiyle karşılaştığımızda MULTI isteğini ilet.

* Bu şekilde MULTI /..../ EXEC bloğunu bir bütün olarak teslim edeceğiz ve

* hem AOF hem de çoğaltma bağlantısı aynı tutarlılığa sahip olacaktır

* ve atomiklik garantileri. * /

eğer (! must_propagate! (c- > cmd- > bayraklar ve CMD_READONLY)) {

execCommandPropagateMulti (c);

must_propagate = 1;

}

çağrı (c, CMD_CALL_FULL);

/ * Komutlar argc / argv'yi değiştirebilir, mstate'i geri yükleyebilir. * /

c- > mstate.commands.argc = c- > argc;

c- > mstate.commands.argv = c- > argv;

c- > mstate.commands.cmd = c- > cmd;

}

c- > argv = orig_argv;

c- > argc = orig_argc;

c- > cmd = orig_cmd;

// 5. Bu müşteriye karşılık gelen işlemle ilgili tüm verileri sıfırlayın

işlemi iptal et (c);

/ * MULTI ise EXEC komutunun da yayılacağından emin olun.

* zaten yayıldı. * /

eğer (must_propagate) server.dirty ++;

handle_monitor:

eğer (listLength (server.monitors)! server.loading)

replicationFeedMonitors (c, server.monitors, c- > db > id, c- > argv, c- > argc);

}

ExecCommand () yöntemi aşağıdaki şeyleri yapacaktır:

Karşılık gelen müşterinin zaten bir işlemde olup olmadığını belirleyin, değilse, doğrudan bir hata döndürür.

İşlemdeki komutun yargılama sırasında yürütülmesi gerekir. Aşağıdaki iki durumda, işlem gerçekleştirilmeyecek ancak bir hata döndürülecektir.

Açılan CLIENT_DIRTY_CAS bayrağına karşılık gelen diğer istemciler tarafından izlenen bir anahtar değiştirildi. Şu anda, hiçbir işlemin yürütülmediğini belirten bir sıfır döndürülecek.

İşlem kuyruğuna CLIENT_DIRTY_EXEC bayrak bitine karşılık gelen bir komut eklendiğinde bir hata oluşur, bu sefer bir execaborterr hatası döndürülür.

Bu müşteri tarafından izlenen tüm anahtarları izle.

İşlem kuyruğundaki tüm komutlar sırayla yürütülür.

Bu müşteriye karşılık gelen işlemle ilgili tüm verileri sıfırlayın.

atmak

Bir işlemi iptal etmek için at komutunu kullanın. Karşılık gelen yöntem, aşağıdaki gibi uygulanan discardCommand () yöntemidir:

void discardCommand (client * c) {

// 1. İlgili müşterinin bir işlemde olup olmadığını kontrol edin

eğer (! (c- > bayraklar ve CLIENT_MULTI)) {

addReplyError (c, "MULTI'sız DISCARD");

dönüş;

}

// 2. İşlemi iptal et

işlemi iptal et (c);

addReply (c, shared.ok);

}

DiscardCommand () yöntemi öncelikle ilgili istemcinin bir işlemde olup olmadığını belirler ve değilse doğrudan bir hata döndürür, aksi takdirde işlemi iptal etmek için discardTransaction () yöntemini çağırır. Yöntem şu şekilde uygulanır:

void discardTransaction (müşteri * c) {

// 1. MULTI / EXEC durumuyla ilgili tüm kaynakları serbest bırakın

freeClientMultiState (c);

// 2. Karşılık gelen durumu başlatın

initClientMultiState (c);

// 3. İstemciye karşılık gelen 3 bayrağı iptal edin

c- > bayraklar = ~ (CLIENT_MULTI | CLIENT_DIRTY_CAS | CLIENT_DIRTY_EXEC);

// 4. izlenen tüm anahtarları izle

unwatchAllKeys (c);

}

Diğer

Atomik: atomiklik

Atomiklik, bir işlemdeki tüm işlemlerin tamamlandığı veya hiç tamamlanmadığı ve bir ara bağlantıda sona ermeyeceği anlamına gelir.

Redis işlemleri için işlem kuyruğundaki tüm komutlar ya yürütülür ya da hiçbiri yürütülmez, bu nedenle Redis işlemleri atomiktir.

Redis'in bir işlem geri alma mekanizması sağlamadığını unutmayın.

Tutarlılık: Tutarlılık

İşlemin tutarlılığı, işlemin başarıyla gerçekleştirilip gerçekleştirilmediğine bakılmaksızın, işlemin yürütme sonucunun, işlemi tutarlı bir durumdan başka bir tutarlı duruma değiştirmek olması gerektiği anlamına gelir.

Komut işlem kuyruğuna katılamazsa (parametre sayısı yanlış mı? Komut mevcut değil mi?), Tüm işlem yürütülmeyecektir. Böylece işlemin tutarlılığı etkilenmeyecektir.

İzleme komutu tarafından izlenen anahtar, yalnızca işlem sırasında diğer müşteriler tarafından değiştirilir ve tüm işlem yürütülmez. İşlemin tutarlılığını etkilemeyecektir.

Komut yürütme hatası. İşlemin yürütülmesi sırasında bir veya daha fazla komut başarısız olursa, sunucu işlemin yürütülmesini kesintiye uğratmayacak ve işlemdeki kalan komutları yürütmeye devam edecek ve yürütülen komutlar hiçbir şekilde etkilenmeyecektir. Yanlış komut çalıştırılmayacak ve veritabanında herhangi bir değişiklik yapılmayacaktır, bu nedenle bu durumda şeylerin tutarlılığı etkilenmeyecektir.

Sunucu çalışmıyor. Sunucu kesintisi durumunda tutarlılık, sunucu tarafından kullanılan kalıcılık yöntemine göre analiz edilebilir.

Kalıcı olmayan modda işlem tutarlıdır. Bu durumda, yeniden başlatmanın ardından veritabanında veri yoktur, bu nedenle her zaman tutarlıdır.

RDB modunda işlemler de tutarlıdır. Sunucu yeniden başlatıldıktan sonra, veriler RDB dosyasına göre geri yüklenebilir, böylece veri tabanı tutarlı bir duruma geri yüklenebilir. Kullanılabilir bir RDB dosyası bulamazsanız, yeniden başlatmanın ardından veritabanı boş kalır ve bu tutarlıdır.

AOF modunda, işlem de tutarlıdır. Sunucu kapandıktan ve yeniden başlatıldıktan sonra, veriler AOF dosyasına dayalı olarak geri yüklenebilir ve böylece veri tabanı tutarlı bir duruma geri yüklenebilir. Kullanılabilen AOF dosyası bulunamazsa, veritabanı yeniden başlatıldıktan sonra boştur, dolayısıyla tutarlıdır.

İzolasyon: izolasyon

Redis, tek işlemli bir programdır ve işlem yürütüldüğünde işlemin kesintiye uğramayacağını ve işlemin işlem kuyruğundaki tüm komutlar yürütülene kadar çalışabileceğini garanti eder. Bu nedenle, Redis işlemleri her zaman yalıtılmıştır.

Dayanıklılık: Dayanıklılık

Redis işlemleri herhangi bir kalıcılık işlevi sağlamaz, bu nedenle işlemlerin dayanıklılığı Redis'in kendisi tarafından kullanılan kalıcılık yöntemine göre belirlenir.

Saf bellek modelinde işlemler kesinlikle dayanıklı değildir.

RDB modunda, işlem gerçekleştirildikten sonra RDB dosyası güncellenmeden önce sunucu başarısız olabilir, bu nedenle RDB modundaki Redis işlemi kalıcı olmaz.

Her zaman AOF modunda, işlemin her komutu başarıyla yürütüldükten sonra, işlem verilerini AOF dosyasına yazmak için hemen fsync veya fdatasync'i çağırır. Bununla birlikte, bu tür bir kaydetme, bir arka plan iş parçacığı tarafından gerçekleştirilir.Ana iş parçacığı, kaydetme başarılı olana kadar bloke olmaz.Bu nedenle, komutun başarılı bir şekilde yürütülmesi ile verilerin sabit diske kaydedilmesi arasında hala çok küçük bir aralık vardır, bu nedenle bu moddaki işlem de yapılır. Kalıcı değil.

Diğer AOF modları her zaman moduna benzer, bu nedenle dayanıklı değildirler.

Sonuç: Redis işlemleri atomikliği, tutarlılığı ve izolasyonu sağlar, ancak dayanıklılığı sağlamaz.

Diğer üç yolu oynamanın hangi yolu çökecek? LOL oyununda zihninizi patlatacak anları sayın
önceki
Lop Nur'un Maceraları | Lu Xinping: Bir uzaylı gibi mavi vahşi doğa, şahsen görmezseniz hayal bile edemezsiniz
Sonraki
Uzunluğu Mercedes-Benz E'den daha uzun, ışıklar A8'den daha göz kamaştırıcı ve fiyatı 500.000'den az Lüks otomobil topluca sallanıyor mu?
Dongfeng Citroen: Nasıl daha çekici hale getirilir?
70'lerin Datsun 280Z davasında doğan zarif bayana saygı
dnf2017 Ulusal Gün hale görünüm listesi seti Ulusal Gün hediye çantası küre nitelikleri
Geçen yıl, büyük iblis hisse senetleri düşük bir seviyede 100 milyon alt pozisyonu ortaya çıkardı. Editör onları yakalamanıza yardımcı oldu
"Genç" meraklıların maceraları
109.800 ve 1.5T güce sahip Trumpchi GM6'ya ne dersiniz?
LOLun en değerli avatarı TOP10 Bu avatarlardan hiçbirini görmemiş olabilirsiniz
100 kilometreden 3 saniyede hızlanma, 2,89 milyon fiyatla, Honda, Ferrari'yi utandırdı
LOL Snake patronu Snake aniden Weibo: SS takımı satıldı
Mide problemlerini görmek için Nobel Ödülü sahibi bulmak hayal değil mi? "Helicobacter Pylori'nin babası" Profesör Barry Marshall bu sabah Dongfang Hastanesinde
Yiwei Lithium'un gün içi günlük limiti, geç baskın ne olacak? Yeni pazara iki yön öncülük ediyor
To Top