Reed - kode Solomon di RAID 6

Ada banyak artikel di Internet tentang pemulihan data dalam array RAID-6 dan bagaimana membuat implementasi Anda sendiri dari array tersebut. Tetapi sebagian besar artikel ini dijejali dengan rumus matematika. Untuk memahami algoritma sebenarnya, Anda harus menghabiskan banyak waktu.



Pada artikel ini saya akan mencoba menunjukkan contoh sederhana dari sistem koreksi kesalahan saya sendiri berdasarkan RAID-6. Secara khusus, pertimbangkan situasi di mana Anda perlu menyediakan redundansi sistem sehingga dapat menahan kegagalan satu atau dua drive.



Sebagai bonus, informasi tentang cara kerja koreksi kesalahan di RAID-5, karena RAID-6 adalah versi RAID-5 yang ditingkatkan.



Gambaran



Katakanlah Anda memiliki tiga disk dengan beberapa data. Sebut saja mereka D1, D2 dan D3. Untuk menggunakan sistem RAID-6, Anda memerlukan dua drive tambahan: PD dan RS. Dalam beberapa menit, saya akan menjelaskan apa kepanjangan dari PD dan RS. Jadi, total ada lima drive: D1, D2, D3, PD dan RS.







Jadi situasinya:



  • D1, D2 dan D3 berisi data sewenang-wenang . Katakanlah foto kucing.

  • Disk khusus PD (Parity Drive, terkadang P dalam dokumentasi) berisi data yang diperbesar secara otomatis dari D1, D2 dan D3.

  • Disk khusus kedua RS (kode Reed-Solomon, kadang-kadang disebut Q) untuk data yang sama seperti PD.


Mari kita lihat bagaimana melakukan operasi dasar pada larik semacam itu.



Bagaimana pemulihan bekerja



Jika Anda menghitung PD dan RS dengan benar, Anda dapat dengan mudah bertahan dari kegagalan hingga dua disk. Prosedur pemulihan tergantung pada drive tertentu yang gagal. Tujuh situasi biasanya dipertimbangkan. Di bawah ini mereka diurutkan dari yang mudah ke yang rumit.



  1. Kehilangan PD (hanya satu disk).







    Kasus yang sangat sederhana. Drive PD hanya berisi data yang dibuat secara otomatis, sehingga dapat dipulihkan menggunakan data asli pada drive D1, D2, dan D3.



  2. : D1, D2 D3 ( ).







    , , , RAID-5: PD . PD, . RS ( ).



  3. RS ( ).







    1: , RS,  β€” .



  4. PD RS ( ).







    1 3. , PD, RS.



  5. RS ( ).







    , . PD, , β„– 2. , RS.



  6. PD ( ).







    . ( D3), PD, . RS (D1 D2), D3. PD. ,  β€” .



  7. ( ).







    . PD, RS .  β€” .


Di bagian selanjutnya, kita akan menjelajahi kasus ini secara lebih rinci dan melihat kode sumber (dengan Python) yang melakukan pemulihan data aktual.



Perlu diingat bahwa array RAID-6 sebenarnya tidak mengalokasikan seluruh drive untuk PD atau RS. Data ini tersebar di semua drive. Pengontrol yang berbeda menggunakan metode yang berbeda: asinkron kiri atau sinkron kanan, mungkin ada pergeseran dalam kaitannya dengan data RAID, latensi, dll. Mari kita kesampingkan diskusi tentang mengapa hal ini terjadi dan seperti apa garis-garis sebenarnya RAID-6. Mari kita fokus secara khusus pada kode Reed-Solomon.



Uji data



Mari kita definisikan "data pengguna". Untuk mempermudah, mari kita setel ukuran setiap "disk" menjadi 5 byte.



Disk Data ASCII Data di HEX
D1



pertama 0x66, 0x69, 0x72, 0x73, 0x74
D2



kedua 0x73, 0x65, 0x63, 0x6e, 0x64
D3



ketiga 0x74, 0x68, 0x69, 0x72, 0x64


Sekarang mari kita lihat lebih dekat skenario yang disebutkan.



Situasi 1. Kehilangan disk PD



Untuk menghasilkan PD, hanya diperlukan disk data pengguna. Dalam kasus kami, ini adalah D1, D2 dan D3. Disk PD hanya XOR dari semua data pengguna.



Untuk menghasilkan offset 0 untuk PD, semua byte dari offset 0 harus di-zip di semua disk. Ditto untuk offset 1 dan seterusnya:



PD [0] = D1 [0] xor D2 [0] xor D3 [0]
PD [1] = D1 [1] xor D2 [1] xor D3 [1]
PD [2] = D1 [2] xor D2 [2] xor D3 [2]
PD [3] = D1 [3] xor D2 [3] xor D3 [3]
PD [4] = D1 [4] xor D2 [4] xor D3 [4]


Contoh:



PD [0] = 0x66 xor 0x73 xor 0x74 => 0x61
PD [1] = 0x69 xor 0x65 xor 0x63 => 0x64
PD [2] = 0x72 xor 0x63 xor 0x69 => 0x78
PD [3] = 0x73 xor 0x6e xor 0x72 => 0x6f
PD [4] = 0x74 xor 0x64 xor 0x64 => 0x74


Ya, itu sangat sederhana. Lakukan ini untuk seluruh disk (dalam kasus kami, 5-byte), dan dapatkan PD yang dibuat dengan benar:



Disk Data di HEX
PD



0x61, 0x64, 0x78, 0x6f, 0x74


Jadi, jika hanya PD yang gagal, agak remeh untuk mengembalikannya dari D1, D2 dan D3.



Situasi 2. Kehilangan salah satu penyimpanan data: D1, D2 atau D3



Ngomong-ngomong, beginilah cara kerja perbaikan kesalahan RAID-5. Jika hanya satu disk data pengguna yang gagal, kita dapat menggunakan disk PD untuk menghitung ulang data pengguna yang hilang.



Misalkan D2 hilang. D1, D3, PD dan RS tetap tersedia. Dalam hal ini, jangan sentuh RS. Hanya drive D1, D3 dan PD yang dibutuhkan. Untuk menghitung data yang hilang, Anda dapat menggunakan fungsi XOR kembali seperti pada situasi sebelumnya.



Untuk memulihkan data pengguna dari offset 0, xorim byte dari offset nol disk data pengguna yang tersisa (D1 dan D3) dengan byte dari offset nol PD. Ulangi untuk offset 1, dan seterusnya:



D2 [0] = D1 [0] xor D3 [0] xor PD [0]
D2 [1] = D1 [1] xor D3 [1] xor PD [1]
D2 [2] = D1 [2] xor D3 [2] xor PD [2]
D2 [3] = D1 [3] xor D3 [3] xor PD [3]
D2 [4] = D1 [4] xor D3 [4] xor PD [4]


Contoh:



D2 [0] = 0x66 xor 0x74 xor 0x61 => 0x73
D2 [1] = 0x69 xor 0x63 xor 0x64 => 0x65 (e)
D2 [2] = 0x72 xor 0x69 xor 0x78 => 0x63 (c)
D2 [3] = 0x73 xor 0x72 xor 0x6f => 0x6e (n)
D2 [4] = 0x74 xor 0x64 xor 0x74 => 0x64 (d)


Seperti yang Anda lihat, sangat mudah untuk memulihkan data dari disk yang hilang. Tidak masalah disk mana yang hilang: fungsi XOR selalu berfungsi.



Situasi 3. Disk RS hilang



Sekarang kode bidang Reed-Solomon dan Galois mulai berlaku. Tapi jangan khawatir, Anda tidak perlu menjadi ahli matematika untuk menggunakannya.



Saat kita hanya kehilangan drive RS atau membuat sistem baru seperti RAID-6, kita hanya perlu membuat ulang kode. Untuk melakukannya, gunakan tabel gflog dan gfilog dengan konten yang tidak dapat diubah, serta data dari drive D1, D2, dan D3 yang ada.



Tabel gflog selalu terlihat seperti ini:



0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf.


Tabel gfilog juga tetap:



0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01.


Tabel ini tidak perlu disertakan dalam program, Anda dapat menggunakan algoritme generasi berikut saat runtime:



# gflog_tables.py

def generate_tables():
    polynomial = 0x11d
    s = 8
    gf_elements = 1 << s

    gflog = gf_elements * [0]
    gfilog = gf_elements * [0]

    b = 1
    for i in range(0, gf_elements):
        gflog[b] = i & 255
        gfilog[i] = b & 255
        b <<= 1
        if b & gf_elements:
            b ^= polynomial

    gflog[1] = 0;
    return (gflog, gfilog)

def dump_table(caption, tab):
    item = 0
    print("--- {} ---".format(caption))
    for i in tab:
        print("0x{:02x}, ".format(i), end="")
        item += 1
        if item % 16 == 0:
            item = 0
            print()
    print("")

(gflog, gfilog) = generate_tables()

# Uncomment if you want to see the tables on the console:
#
# dump_table("gflog", gflog)
# dump_table("gfilog", gfilog)
      
      





Setelah tabel dideklarasikan, beberapa operasi perlu didefinisikan. Sekarang kita bekerja di bidang terbatas ( bidang Galois), jadi operasi aritmatika dasar memiliki implementasi yang berbeda (meskipun artinya agak mirip). Anda perlu mendefinisikan kembali operasi dasar - penjumlahan, perkalian dan pembagian:



# rs_functions.py

from gflog_tables import *

# Addition
def gf_add(*args):
    result = 0
    for arg in args:
        result ^= arg

    return result

# Indexing
# First drive is 1, second drive is 2, etc...
def gf_drive(index):
    global gfilog

    return gfilog[index - 1]

# Multiplication
def gf_mul(a, b):
    global gflog
    global gfilog

    if a == 0 or b == 0:
        return 0
    else:
        return gfilog[(gflog[a] + gflog[b]) % 255]

# Division helper
def sub_gf8(a, b):
    if a > b:
        return a - b
    else:
        return (255 - (0 - (a - b)))

# Division
def gf_div(a, b):
    global gfilog
    global gflog

    return gfilog[sub_gf8(gflog[a], gflog[b])]
      
      





Karena fungsi helper dideklarasikan, mari kita coba menghasilkan data disk RS.



# case 3 -- recover_rs.py

from rs_functions import *

# Here are our drives, together with their data.
image1 = [ ord('f'), ord('i'), ord('r'), ord('s'), ord('t') ]
image2 = [ ord('s'), ord('e'), ord('c'), ord('n'), ord('d') ]
image3 = [ ord('t'), ord('h'), ord('i'), ord('r'), ord('d') ]

# This is a placeholder for our RS drive. It will be regenerated
# in the lines below.
imageRS = [0] * 5

# And this is our loop that generates the RS data using nothing more
# than the user data drives.
for i in range(0, 5):
    imageRS[i] = gf_add(gf_mul(gf_drive(1), image1[i]),
                        gf_mul(gf_drive(2), image2[i]),
                        gf_mul(gf_drive(3), image3[i]))

dump_table("imageRS", imageRS)
      
      





Setelah menjalankan skrip recover_rs.py



, disk RS berisi data berikut:



Disk Data di HEX
RS



0x4d, 0x1e, 0x0d, 0x7a, 0x31


Saat ini, drive D1, D2, dan D3 dilindungi oleh algoritme koreksi kesalahan RAID-6 lengkap, karena kami telah membuat PD dan RS dengan benar.



Penting untuk diingat bahwa data RS saat ini hanya valid untuk D1, D2 dan D3 dalam urutan tertentu . Jadi, RS untuk D1, D2, dan D3 akan berbeda dari D3, D2, dan D1 meskipun data sebenarnya pada disk sama. Ini penting untuk diingat karena saat memulihkan data RAID-6, Anda perlu mengetahui urutan disk yang benar dalam larik. Untungnya, jika lariknya kecil, Anda dapat memaksa data RS yang akan dibuat untuk menemukan urutan disk yang benar.



Situasi 4. Kehilangan PD dan RS



Ini juga merupakan situasi yang sederhana: pertama kita jalankan skenario # 1, dan kemudian # 3. Saya



ulangi, dalam hal ini data pengguna tidak terpengaruh. Kita bisa menggunakannya untuk membuat PD. Kemudian untuk membuat RS. Kedua kasus tersebut telah dijelaskan pada poin 1 dan 3.



Situasi 5. Hilangnya RS dan satu disk data



Dan di sini tidak sulit. Kami kehilangan satu disk data, tetapi kami masih memiliki PD, jadi kami dapat menjalankan skenario # 2 untuk memulihkan disk data yang hilang. Kemudian gunakan semua disk data untuk regenerasi RS, seperti dalam skenario # 3. Set lengkap disk sekarang sudah pulih.



Situasi 6. Kehilangan PD dan satu disk data



Pendekatan umum adalah pertama-tama memulihkan disk data yang hilang menggunakan disk lain yang dikombinasikan dengan RS, dan kemudian, setelah semua disk data dipulihkan, lanjutkan untuk membuat ulang PD (skenario # 2).



Dalam situasi ini, Anda harus melakukan beberapa perhitungan. Misalkan bersama dengan PD kita kehilangan data disk D2. Jadi kami memiliki stok D1, D3 dan RS.



Berkat disk RS, kami dapat memulihkan D2 dengan menggabungkan D1, D3, dan RS, seperti ini:



# case 6 -- recover_d2_and_pd.py

from rs_functions import *

# We have these drives...
image1 = [ ord('f'), ord('i'), ord('r'), ord('s'), ord('t') ]
image3 = [ ord('t'), ord('h'), ord('i'), ord('r'), ord('d') ]
imageRS = [ 0x4d, 0x1e, 0x0d, 0x7a, 0x31 ]

# ...and these drives are dead
imagePD = [0] * 5
image2 = [0] * 5

for i in range(0, 5):
    partialRS = gf_add(gf_mul(gf_drive(1), image1[i]),
                       imageRS[i],  # Use RS drive instead of the dead drive.
                       gf_mul(gf_drive(3), image3[i]))

    # gf_drive(2) is our dead drive.
    div_result = gf_div(1, gf_drive(2))

    # This will generate the data from the dead D2 drive.
    image2[i] = gf_mul(div_result, partialRS)

    # This will generate the data from the dead PD drive.
    imagePD[i] = gf_add(image1[i], image2[i], image3[i])

dump_table("image2", image2)
dump_table("imagePD", imagePD)
      
      





Pertama, Anda perlu menghasilkan nilai partialRS



dengan menambahkan (gf_add) nilai yang dikembalikan gf_mul



untuk semua byte dari semua disk yang valid bersama dengan nilai RS, bukan disk data yang hilang (dalam kasus kami, D2).



Kami kemudian menggunakan nilai partialRS



untuk meregenerasi data D2 dengan membaginya dengan indeks disk mati ( gf_drive(2)



) dan mengalikan hasilnya dengan partialRS



. Argumen gf_drive(2)



menunjukkan indeks disk mati kami. Jika D1 gagal, kami akan gunakan di sini gf_drive(1)



.



Setelah meregenerasi D2, pulihkan semua disk data. Dalam hal ini, kami melakukan regenerasi PD seperti pada skenario # 1: pada kode di atas, ini dilakukan dengan menambahkan (gf_add) data dari semua disk. Jika kamu ingatgf_add



Bidang Galois adalah operasi XOR sederhana, jadi alih-alih mengoreksi byte secara manual dari semua disk data, Anda dapat menggunakan gf_add



.



Situasi 7. Kehilangan dua pengumpul data



Ini adalah skenario yang paling menarik dan paling sulit. Misalkan disk D2 dan D3 rusak. Dalam hal ini, Anda harus menggunakan disk D1, PD, dan RS untuk membuat ulang disk yang hilang.



Ini adalah pendekatan yang berbeda dari kasus sebelumnya. Pendekatan umum adalah pertama-tama menghasilkan data untuk D2 dan kemudian menggunakan perkiraan yang sama seperti dalam skenario # 2 untuk menghasilkan data untuk D3. Ini kodenya:



# case 7 -- recover_d2_and_d3.py

from rs_functions import *

# These drives are still alive.
image1 = [ ord('f'), ord('i'), ord('r'), ord('s'), ord('t') ]
imagePD = [ 0x61, 0x64, 0x78, 0x6f, 0x74 ]
imageRS = [ 0x4d, 0x1e, 0x0d, 0x7a, 0x31 ]

# These drives are dead, we can't read from them.
image2 = [0] * 5
image3 = [0] * 5

for i in range(0, 5):
    partialPD = gf_add(image1[i]) # add other drives if they exist
    partialRS = gf_add(gf_mul(gf_drive(1), image1[i])) # add other drives if they exist

    g = gf_div(1, gf_add(gf_drive(2), gf_drive(3)))
    xoredPD = gf_add(partialPD, imagePD[i])
    xoredRS = gf_add(partialRS, imageRS[i])
    mid = gf_add(gf_mul(gf_drive(3), xoredPD), xoredRS) # gf_drive(3) is the second drive we've lost

    # Regenerate data for D2.
    data = gf_mul(mid, g)
    image2[i] = data

    # Regenerate data for D3.
    image3[i] = gf_add(image1[i], image2[i], imagePD[i])

    # or:
    #
    # image3[i] = gf_add(data, xoredPD)

dump_table("image2", image2)
dump_table("image3", image3)
      
      





Pertama, Anda perlu menambahkan semua byte dari semua disk data yang ada untuk dibuat partialPD



. Dalam contoh ini, kami hanya memiliki satu disk data, jadi parameternya partialPD



adalah konten disk D1. Tapi array RAID-6 menjangkau banyak drive. Oleh karena itu, jika kita memiliki lebih dari satu disk data, misalnya tiga disk data langsung, maka perhitungan partialPD akan terlihat seperti ini:



partialPD = gf_add(image1[i], image2[i], image3[i])
      
      





Selanjutnya kita membutuhkan parameter partialRS



. Itu dapat dihitung dengan menambahkan data dari disk yang ada sebagai berikut:



partialRS = gf_add(A, B, C, ..., Z)

where A = gf_mul(gf_drive(1), image1[i])
      B = gf_mul(gf_drive(2), image2[i]) if we have drive 2
      C = gf_mul(gf_drive(3), image3[i]) if we have drive 3

etc.
      
      





Dalam kasus kami, hanya ada satu drive data (D1) yang tersisa, jadi milik kami partialRS



sederhana gf_mul(gf_drive(1), image1[i])



.



Kemudian Anda perlu membuat parameter g



dengan membaginya satu dengan jumlah indeks disk yang mati (D2 dan D3).



Berikutnya adalah parameter xoredPD



; itu dihitung dengan menambahkan konten PD ke parameter yang partialPD



dihitung sebelumnya. Parameter selanjutnya xoredRS



dihitung dengan cara yang sama, dengan menambahkannya partialRS



ke konten RS.



Sekarang untuk bagian yang sulit. Anda dapat menghitung data dari disk pertama yang rusak, yaitu dari disk D2. Untuk melakukan ini, kalikan indeks dari disk kedua yang rusak (D3) dengan parameter xoredPD



dan tambahkan parameter ke hasilnya xoredRS



. Kemudian, setelah mengalikan hasilnya dengan parameterg



, kami mendapatkan isi dari disk D2.



Karena kami baru saja memulihkan data untuk D2, kasus ini tidak berbeda dengan skenario # 2 - kehilangan satu disk data (D3). Untuk membuat drive D3, semua drive data langsung (D1 dan D2) harus ditambahkan ke PD.



Selesai! Kami mengembalikan satu set lengkap disk.



Epilog



Saya memilih Python untuk menunjukkan bahwa mengoreksi kesalahan dengan kode Reed-Solomon tidak membutuhkan banyak daya pemrograman atau pemrosesan. Semuanya sangat cepat dan implementasinya bisa sangat kompak. Tentu saja, implementasi yang lebih efisien harus ditulis dengan pemrosesan paralel. Karena setiap byte dihitung secara independen satu sama lain, paralelisasi tidak sulit.



Perlu dicatat bahwa metode pemulihan data yang dijelaskan tidak harus digunakan pada disk fisik terpisah. "Disk" dapat dianggap sebagai "buffer" dalam proses pengiriman data melalui saluran yang tidak dapat diandalkan, dan koreksi kesalahan tersebut tetap efektif. Di sini, komputasi yang lebih intensif diperlukan daripada dengan kode Hamming, tetapi dua aliran yang jatuh dapat dimunculkan. Ini adalah fitur ketahanan yang kuat.



Tentu saja, RAID-6 jauh dari penemuan baru, dan kode Reed-Solomon bahkan lebih tua. Mereka digunakan kembali dalam misi Voyager 2 , yang cukup keren.



Di antara alternatif yang lebih modern untuk kode Reed-Solomon adalah kode turbo  - saya harap saya akan memiliki kesempatan untuk menggalinya juga.



All Articles