Rumah  >  Artikel  >  pangkalan data  >  Mari bercakap tentang transaksi dalam Redis: mod transaksi, skrip Lua

Mari bercakap tentang transaksi dalam Redis: mod transaksi, skrip Lua

青灯夜游
青灯夜游ke hadapan
2023-04-10 19:29:361501semak imbas

Artikel ini akan memberi anda pemahaman yang menyeluruh tentang transaksi Redis dan membandingkan dua mod transaksi Redis (mod transaksi dan skrip Lua).

Tepatnya, transaksi Redis termasuk dua mod: Mod transaksi dan Skrip Lua.

Mula-mula mari kita bercakap tentang kesimpulan:

Model transaksi Redis mempunyai ciri-ciri berikut:

  • Pengasingan dijamin
  • Ketahanan tidak boleh dijamin;
  • Ia mempunyai tahap atomicity tertentu, tetapi tidak menyokong rollback
  • Konsep konsistensi adalah berbeza. Urus niaga Redis boleh menjamin konsistensi.

Tetapi skrip Lua mempunyai senario yang lebih praktikal Ia adalah satu lagi bentuk urus niaga Ia mempunyai tahap atomicity tertentu, tetapi apabila skrip melaporkan ralat, urus niaga tidak akan ditarik balik. Skrip Lua boleh memastikan pengasingan, dan boleh menyokong dengan sempurna langkah seterusnya bergantung pada keputusan langkah sebelumnya . [Cadangan berkaitan: Tutorial Video Redis]

Mod skrip Lua hampir di mana-mana, seperti kunci teragih, baris gilir kelewatan, rampasan sampul merah dan senario lain.

1 Prinsip Transaksi

Transaksi Redis termasuk arahan berikut:

序号 命令及描述
1 MULTI 标记一个事务块的开始。
2 EXEC 执行所有事务块内的命令。
3 DISCARD 取消事务,放弃执行事务块内的所有命令。
4 WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
5 UNWATCH 取消 WATCH 命令对所有 key 的监视。

Transaksi terdiri daripada tiga peringkat:

  1. Transaksi dibuka, menggunakan MULTI, arahan ini menandakan klien melaksanakan perintah bertukar daripada keadaan bukan transaksi kepada perintah
  2. Selepas memasuki baris gilir, MULTI memulakan transaksi, arahan pelanggan tidak akan dilaksanakan serta-merta, tetapi akan dimasukkan ke dalam baris gilir transaksi; Jika arahan EXEC diterima, arahan dalam baris gilir transaksi akan dilaksanakan. Jika ia DISCARD, transaksi akan dibuang.
  3. Berikut menunjukkan contoh transaksi.

Ada soalan di sini? Bolehkah kunci Redis diubah suai semasa memulakan transaksi?
1
 redis> MULTI 
2
 OK
3
 redis> SET msg "hello world"
4
 QUEUED
5
 redis> GET msg
6
 QUEUED
7
 redis> EXEC
8
 1) OK
9
 1) hello world

Sebelum transaksi melaksanakan perintah EXEC, kunci Redis masih boleh diubah suai

. Sebelum transaksi dimulakan, kita boleh menggunakan arahan jam tangan untuk memantau kekunci Redis. Sebelum urus niaga dilaksanakan, kami mengubah suai nilai kunci, dan urus niaga gagal dan mengembalikan

tiada

.

Melalui contoh di atas, arahan jam tangan boleh

mencapai kesan yang serupa dengan penguncian optimistik

.

2 ASID transaksi

2.1 AtomicityAtomicity bermaksud: satu transaksi Semua operasi dalam sama ada siap atau tidak siap, dan tidak akan berakhir pada mana-mana peringkat pertengahan. Jika ralat berlaku semasa pelaksanaan urus niaga, ia akan digulung semula ke keadaan sebelum urus niaga bermula, seolah-olah urus niaga itu tidak pernah dilaksanakan.

Contoh pertama:

Sebelum melaksanakan arahan EXEC, arahan operasi yang dihantar oleh klien adalah salah, seperti ralat sintaks atau arahan yang tidak wujud.

Dalam contoh ini, kami menggunakan perintah yang tidak wujud, menyebabkan enqueue gagal dan keseluruhan transaksi gagal dilaksanakan.
1
 redis> MULTI
2
 OK
3
 redis> SET msg "other msg"
4
 QUEUED
5
 redis> wrongcommand  ### 故意写错误的命令
6
 (error) ERR unknown command 'wrongcommand' 
7
 redis> EXEC
8
 (error) EXECABORT Transaction discarded because of previous errors.
9
 redis> GET msg
10
 "hello world"

Contoh kedua:

Apabila operasi urus niaga dimasukkan ke dalam baris gilir, jenis data perintah dan operasi tidak sepadan.

Dalam contoh ini, jika ralat berlaku apabila Redis melaksanakan perintah EXEC, Redis tidak akan menamatkan pelaksanaan perintah lain dan transaksi tidak akan ditarik balik kerana arahan tertentu gagal dilaksanakan.
1
 redis> MULTI  
2
 OK
3
 redis> SET msg "other msg"
4
 QUEUED
5
 redis> SET mystring "I am a string"
6
 QUEUED
7
 redis> HMSET mystring name  "test"
8
 QUEUED
9
 redis> SET msg "after"
10
 QUEUED
11
 redis> EXEC
12
 1) OK
13
 2) OK
14
 3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
15
 4) OK
16
 redis> GET msg
17
 "after"

Ringkasnya, pemahaman saya tentang atomicity transaksi Redis adalah seperti berikut:

Apabila ralat dilaporkan apabila arahan ditambahkan pada baris gilir, pelaksanaan transaksi akan ditinggalkan untuk memastikan atomicity; perintah
  1. Ia adalah perkara biasa apabila menyertai baris gilir, tetapi ralat dilaporkan selepas melaksanakan perintah EXEC, dan atomicity tidak dijamin; >Urus niaga Redis hanya mempunyai atomicity tertentu dalam keadaan tertentu
  2. .

2.2 Pengasingan

Pengasingan pangkalan data bermakna pangkalan data membenarkan berbilang transaksi serentak untuk membaca, menulis dan mengubah suai datanya pada masa yang sama masa. Keupayaan dan pengasingan boleh menghalang ketidakkonsistenan data akibat pelaksanaan silang apabila berbilang transaksi dilaksanakan secara serentak. Pengasingan urus niaga terbahagi kepada tahap yang berbeza, iaitu:

Baca tanpa komitmen (baca tanpa komitmen)

Baca komited (baca komited)

Boleh diulang baca
  • Boleh Bersiri
  • Pertama sekali, ia perlu jelas: Redis tidak mempunyai konsep tahap pengasingan transaksi. Di sini kita membincangkan pengasingan Redis:
  • Dalam senario serentak, sama ada transaksi boleh mengelak daripada campur tangan antara satu sama lain
  • .
  • Kita boleh membahagikan pelaksanaan transaksi kepada dua peringkat:
Sebelum perintah EXEC dilaksanakan

dan Selepas arahan EXEC dilaksanakan, dan bincangkannya secara berasingan.

Sebelum melaksanakan perintah EXECDalam bahagian prinsip transaksi, kami mendapati bahawa kunci Redis masih boleh diubah suai sebelum transaksi dilaksanakan. Pada masa ini, anda boleh menggunakan

mekanisme WATCH
    untuk mencapai kesan penguncian optimistik.
Selepas arahan EXEC dilaksanakan

Oleh kerana Redis ialah arahan pelaksanaan satu-thread, selepas arahan EXEC dilaksanakan, Redis akan memastikan semua arahan dalam arahan baris gilir dilaksanakan. Ini memastikan pengasingan transaksi.

  1. 2.3 Kegigihan

Kegigihan pangkalan data bermaksud: selepas transaksi selesai, pengubahsuaian data adalah kekal, walaupun sistem gagal Ia tidak akan hilang sama ada. Sama ada data Redis dikekalkan bergantung pada mod konfigurasi kegigihan Redis.

Tanpa RDB atau AOF dikonfigurasikan, ketahanan urus niaga tidak boleh dijamin

Menggunakan mod RDB, selepas transaksi dilaksanakan, sebelum syot kilat RDB seterusnya dilaksanakan, jika Sekiranya berlaku masa henti, ketahanan transaksi tidak dapat dijamin

menggunakan mod AOF; tiga pilihan konfigurasi mod AOF, tidak dan setiap saat, akan menyebabkan kehilangan data. sentiasa boleh menjamin ketahanan urus niaga, tetapi kerana prestasinya terlalu lemah, ia biasanya tidak disyorkan untuk digunakan dalam persekitaran pengeluaran.
  1. Ringkasnya,
  2. ketahanan transaksi redis tidak dapat dijamin
  3. .

2.4 Ketekalan

Konsep konsistensi sentiasa mengelirukan Dalam maklumat yang saya cari, terdapat dua definisi yang berbeza.

  1. Wikipedia

Mari kita lihat dulu definisi konsistensi di Wikipedia:

Konsistensi memastikan bahawa transaksi hanya boleh membawa pangkalan data dari satu keadaan yang sah kepada yang lain, mengekalkan invarian pangkalan data: sebarang data yang ditulis ke pangkalan data mestilah sah mengikut semua peraturan yang ditetapkan, termasuk kekangan, lata, pencetus, dan sebarang kombinasi daripadanya. Ini menghalang rasuah pangkalan data oleh transaksi haram, tetapi tidak menjamin bahawa transaksi adalah betul. Integriti rujukan menjamin kunci utama – hubungan kunci asing mana-mana data yang ditulis ke pangkalan data mestilah sah mengikut semua peraturan yang ditetapkan

”.

Bagaimana untuk memahami kekangan? Berikut ialah petikan daripada soalan Zhihu Bagaimana untuk memahami ketekalan dalaman dan ketekalan luaran pangkalan data, dan petikan yang dijawab oleh Han Fusheng, pakar R&D OceanBase di Ant Financial:

"Kekangan" ditentukan oleh pangkalan data Pengguna memberitahu pangkalan data bahawa pengguna memerlukan data mesti mematuhi kekangan ini atau itu. Apabila data diubah suai, pangkalan data akan menyemak sama ada data masih memenuhi kekangan Jika kekangan tidak lagi berpuas hati, operasi pengubahsuaian tidak akan berlaku.

Dua jenis kekangan yang paling biasa dalam pangkalan data hubungan ialah "kekangan unik" dan "kekangan integriti". integriti rujukan yang ditakrifkan juga memastikan ketekalan atribut yang sama dalam jadual yang berbeza.

"Konsistensi dalam ACID" sangat mudah digunakan sehingga ia telah dicairkan ke dalam darah kebanyakan pengguna secara sedar akan menambah kekangan yang diperlukan semasa mereka bentuk jadual, dan pangkalan data juga akan Kekangan ini akan dikuatkuasakan dengan ketat. .

Jadi

ketekalan transaksi adalah berkaitan dengan kekangan yang telah ditetapkan, memastikan kekangan memastikan ketekalan

.

Mari kita lihat dengan lebih dekat ayat ini:
Ini menghalang rasuah pangkalan data oleh transaksi haram, tetapi tidak menjamin bahawa transaksi itu betul

. Anda mungkin masih keliru selepas menulis ini. Mari kita ambil contoh klasik

pindahan

. Kami memulakan urus niaga Baki awal pada akaun Zhang San dan Li Si adalah 1,000 yuan, dan tiada kekangan pada medan baki. Zhang San memindahkan 1,200 yuan kepada Li Si. Baki Zhang San dikemas kini kepada -200, dan baki Li Si dikemas kini kepada 2200.

Dari peringkat aplikasi, transaksi ini jelas menyalahi undang-undang, kerana dalam senario sebenar, baki pengguna tidak boleh kurang daripada 0, tetapi ia benar-benar mengikut kekangan pangkalan data, jadi dari peringkat pangkalan data, transaksi ini adalah masih terjamin konsistensi. Konsistensi transaksi Redis bermakna transaksi Redis mematuhi kekangan pangkalan data semasa pelaksanaan dan tidak mengandungi data ralat yang menyalahi undang-undang atau tidak sah.

Kami membincangkan tiga senario pengecualian masing-masing:

Sebelum melaksanakan arahan EXEC, arahan operasi yang dihantar oleh pelanggan adalah salah, transaksi ditamatkan dan data kekal konsisten;

    Selepas melaksanakan perintah EXEC, jenis data perintah dan operasi tidak sepadan Ralat akan dilaporkan untuk arahan yang salah, tetapi transaksi tidak akan ditamatkan kepada arahan yang salah, tetapi akan terus melaksanakan. Perintah yang betul dilaksanakan secara normal, dan arahan yang salah melaporkan ralat Dari perspektif ini, data juga boleh mengekalkan konsistensi
  1. Semasa pelaksanaan urus niaga, perkhidmatan Redis menurun. . Di sini anda perlu mempertimbangkan mod kegigihan konfigurasi perkhidmatan.
  2. Mod memori tanpa kegigihan: Selepas perkhidmatan dimulakan semula, pangkalan data tidak menyimpan data, jadi data kekal konsisten;
  3. Mod RDB / AOF: Selepas perkhidmatan dimulakan semula, Redis Restore; data melalui fail RDB/AOF dan pangkalan data dipulihkan kepada keadaan yang konsisten.

    • Ringkasnya,
    • di bawah semantik bahawa teras konsistensi adalah kekangan, transaksi Redis boleh menjamin konsistensi
    • .
"Merancang Aplikasi Intensif Data"

Buku ini ialah buku suci untuk bermula dengan sistem teragih. Terdapat penjelasan tentang ACID dalam bab transaksi:

Atomicity, pengasingan dan ketahanan adalah sifat pangkalan data, manakala konsistensi (dalam pengertian ACID ) adalah sifat aplikasi. Aplikasi mungkin bergantung pada sifat atomicity dan pengasingan pangkalan data untuk mencapai konsistensi, tetapi ia tidak bergantung kepada pangkalan data sahaja, oleh itu, huruf C tidak benar-benar tergolong dalam ACID.

Atomicity, pengasingan dan ketahanan adalah sifat pangkalan data, manakala konsistensi (dalam erti kata ACID) ialah sifat aplikasi. Aplikasi mungkin bergantung pada sifat atomicity dan pengasingan pangkalan data untuk mencapai konsistensi, tetapi ini tidak bergantung pada pangkalan data semata-mata. Oleh itu, huruf C tidak tergolong dalam ACID.

Banyak kali, konsistensi yang telah kita perjuangkan sebenarnya merujuk kepada

konsistensi selaras dengan dunia nyata

Konsistensi di dunia nyata adalah matlamat utama urusan.

Untuk mencapai konsistensi di dunia nyata, perkara berikut perlu dipenuhi:

  1. Jaminan atomicity, ketahanan dan pengasingan Jika ciri-ciri ini tidak dapat dijamin, maka konsistensi transaksi tidak boleh dijamin
  2. Kekangan pangkalan data itu sendiri, seperti panjang rentetan tidak boleh melebihi sekatan lajur atau kekangan keunikan;
  3. Tahap perniagaan juga perlu dijamin.

2.5 Ciri Transaksi

Kami biasanya memanggil Redis sebagai pangkalan data dalam memori, yang berbeza daripada pangkalan data hubungan tradisional untuk memberikan Prestasi yang lebih tinggi, kelajuan penulisan yang lebih pantas, beberapa baki telah dibuat pada peringkat reka bentuk dan pelaksanaan, dan ia tidak dapat menyokong sepenuhnya transaksi ACID.

Transaksi Redis mempunyai ciri-ciri berikut:

  • menjamin pengasingan; tidak disokong;
  • Konsep konsistensi adalah berbeza. Diandaikan bahawa transaksi Redis boleh menjamin konsistensi di bawah semantik bahawa teras konsistensi adalah kekangan.
  • Dari perspektif kejuruteraan, dengan mengandaikan bahawa setiap langkah dalam operasi transaksi perlu bergantung pada hasil yang dikembalikan oleh langkah sebelumnya, penguncian optimistik perlu dilaksanakan melalui jam tangan.
3 Skrip Lua

3.1 Pengenalan

Lua ditulis dalam standard C. Kod ini ringkas dan cantik, serta boleh disusun dan dijalankan pada hampir semua sistem pengendalian dan platform. Skrip Lua boleh dipanggil dengan mudah oleh kod C/C++, dan juga boleh memanggil fungsi C/C++ secara bergilir-gilir, yang menjadikan Lua digunakan secara meluas dalam aplikasi.

Skrip Lua telah membuat percikan besar dalam bidang permainan "Westward Journey II" dan "World of Warcraft" kedua-duanya menggunakan skrip Lua secara meluas. Skrip Lua boleh dilihat dalam get laluan api yang telah dihubungi oleh jurutera bahagian belakang Java, seperti

Openresty

dan

Kong

. Bermula dari Redis versi 2.6.0, penterjemah Lua terbina dalam Redis boleh menjalankan skrip Lua dalam Redis. Faedah menggunakan skrip Lua:

Mengurangkan overhed rangkaian. Hantar berbilang permintaan serentak dalam bentuk skrip untuk mengurangkan kependaman rangkaian.

Operasi atom. Redis akan melaksanakan keseluruhan skrip secara keseluruhan, dan tiada arahan lain akan disisipkan di tengah.
  • Guna semula. Skrip yang dihantar oleh pelanggan akan disimpan secara kekal dalam Redis dan pelanggan lain boleh menggunakan semula skrip ini tanpa menggunakan kod untuk melengkapkan logik yang sama.
  • Perintah biasa untuk skrip Redis Lua:
  • 3.2 EVAL 命令

    命令格式:

    1
     EVAL script numkeys key [key ...] arg [arg ...]

    说明:

    • script是第一个参数,为 Lua 5.1脚本;
    • 第二个参数numkeys指定后续参数有几个 key;
    • key [key ...],是要操作的键,可以指定多个,在 Lua 脚本中通过KEYS[1], KEYS[2]获取;
    • arg [arg ...],参数,在 Lua 脚本中通过ARGV[1], ARGV[2]获取。

    简单实例:

    1
     redis> eval "return ARGV[1]" 0 100 
    2
     "100"
    3
     redis> eval "return {ARGV[1],ARGV[2]}" 0 100 101
    4
     1) "100"
    5
     2) "101"
    6
     redis> eval "return {KEYS[1],KEYS[2],ARGV[1]}" 2 key1 key2 first second
    7
     1) "key1"
    8
     2) "key2"
    9
     3) "first"
    10
     4) "second"

    下面演示下 Lua 如何调用 Redis 命令 ,通过redis.call()来执行了 Redis 命令 。

    1
     redis> set mystring 'hello world'
    2
     OK
    3
     redis> get mystring
    4
     "hello world"
    5
     redis> EVAL "return redis.call('GET',KEYS[1])" 1 mystring
    6
     "hello world"
    7
     redis> EVAL "return redis.call('GET','mystring')" 0
    8
     "hello world"

    3.3 EVALSHA 命令

    使用 EVAL 命令每次请求都需要传输 Lua 脚本 ,若 Lua 脚本过长,不仅会消耗网络带宽,而且也会对 Redis 的性能造成一定的影响。

    思路是先将 Lua 脚本先缓存起来 , 返回给客户端 Lua 脚本的 sha1 摘要。 客户端存储脚本的 sha1 摘要 ,每次请求执行 EVALSHA 命令即可。

    EVALSHA 命令基本语法如下:

    1
     redis> EVALSHA sha1 numkeys key [key ...] arg [arg ...]

    实例如下:

    1
     redis> SCRIPT LOAD "return 'hello world'"
    2
     "5332031c6b470dc5a0dd9b4bf2030dea6d65de91"
    3
     redis> EVALSHA 5332031c6b470dc5a0dd9b4bf2030dea6d65de91 0
    4
     "hello world"

    4 事务 VS Lua 脚本

    从定义上来说, Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快

    因为脚本功能是 Redis 2.6 才引入的, 而事务功能则更早之前就存在了, 所以 Redis 才会同时存在两种处理事务的方法。

    不过我们并不打算在短时间内就移除事务功能, 因为事务提供了一种即使不使用脚本, 也可以避免竞争条件的方法, 而且事务本身的实现并不复杂。

    -- redis.io/

    Lua 脚本是另一种形式的事务,他具备一定的原子性,但脚本报错的情况下,事务并不会回滚。Lua 脚本可以保证隔离性,而且可以完美的支持后面的步骤依赖前面步骤的结果

    Lua 脚本模式的身影几乎无处不在,比如分布式锁、延迟队列、抢红包等场景。

    不过在编写 Lua 脚本时,要注意如下两点:

  1. 为了避免 Redis 阻塞,Lua 脚本业务逻辑不能过于复杂和耗时;
  2. 仔细检查和测试 Lua 脚本 ,因为执行 Lua 脚本具备一定的原子性,不支持回滚。

更多编程相关知识,请访问:编程视频!!

Atas ialah kandungan terperinci Mari bercakap tentang transaksi dalam Redis: mod transaksi, skrip Lua. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.cn. Jika ada pelanggaran, sila hubungi admin@php.cn Padam