ВысокоуровнСвая рСпликация Π² Π‘Π£Π‘Π” Tarantool

ΠŸΡ€ΠΈΠ²Π΅Ρ‚, я занимаюсь созданиСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ для Π‘Π£Π‘Π” Tarantool β€” это разработанная Π² Mail.ru Group ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠ°, ΡΠΎΠ²ΠΌΠ΅Ρ‰Π°ΡŽΡ‰Π°Ρ Π² сСбС Π²Ρ‹ΡΠΎΠΊΠΎΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π‘Π£Π‘Π” ΠΈ сСрвСр ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° языкС Lua. Высокая ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ, основанных Π½Π° Tarantool, достигаСтся Π² частности Π·Π° счСт ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ in-memory Ρ€Π΅ΠΆΠΈΠΌΠ° Π‘Π£Π‘Π” ΠΈ возмоТности выполнСния бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ прилоТСния Π² Π΅Π΄ΠΈΠ½ΠΎΠΌ адрСсном пространствС с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ. ΠŸΡ€ΠΈ этом обСспСчиваСтся ΠΏΠ΅Ρ€ΡΠΈΡΡ‚Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Ρ… с использованиСм ACID-Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ (Π½Π° дискС вСдСтся WAL-ΠΆΡƒΡ€Π½Π°Π»). Π’ Tarantool имССтся встроСнная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΈ ΡˆΠ°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ. Начиная с вСрсии 2.1, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ запросы Π½Π° языкС SQL. Tarantool ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ исходный ΠΊΠΎΠ΄ ΠΈ распространяСтся ΠΏΠΎΠ΄ Π»ΠΈΡ†Π΅Π½Π·ΠΈΠ΅ΠΉ Simplified BSD. Π’Π°ΠΊΠΆΠ΅ имССтся коммСрчСская Enterprise-вСрсия.

ВысокоуровнСвая рСпликация Π² Π‘Π£Π‘Π” Tarantool
Feel the power! (…aka enjoy the performance)

ВсС пСрСчислСнноС Π΄Π΅Π»Π°Π΅Ρ‚ Tarantool ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠΎΠΉ для создания высоконагруТСнных ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… с Π‘Π”. Π’ Ρ‚Π°ΠΊΠΈΡ… прилоТСниях часто Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

Как Π±Ρ‹Π»ΠΎ сказано Π²Ρ‹ΡˆΠ΅, Π² Tarantool Π΅ΡΡ‚ΡŒ встроСнная рСпликация Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π΅Π΅ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ… всСх Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ, содСрТащихся Π² ΠΆΡƒΡ€Π½Π°Π»Π΅ мастСра (WAL). ΠžΠ±Ρ‹Ρ‡Π½ΠΎ такая рСпликация (Π±ΡƒΠ΄Π΅ΠΌ Π΄Π°Π»Π΅Π΅ Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΅Π΅ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для обСспСчСния отказоустойчивости прилоТСния ΠΈ/ΠΈΠ»ΠΈ для распрСдСлСния Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΎΠ΄Π°ΠΌΠΈ кластСра.

ВысокоуровнСвая рСпликация Π² Π‘Π£Π‘Π” Tarantool
Рис. 1. РСпликация Π²Π½ΡƒΡ‚Ρ€ΠΈ кластСра

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ сцСнария ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π΄Π°Π½Π½Ρ‹Ρ…, созданных Π² ΠΎΠ΄Π½ΠΎΠΉ Π‘Π”, Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ Π‘Π” для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ/ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π°. Π’ послСднСм случаС Π±ΠΎΠ»Π΅Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ использованиС высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ β€” Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ бизнСс-Π»ΠΎΠ³ΠΈΠΊΠΈ прилоТСния. Π’.Π΅. ΠΌΡ‹ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π³ΠΎΡ‚ΠΎΠ²ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, встроСнноС Π² Π‘Π£Π‘Π”, Π° своими силами Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π²Π½ΡƒΡ‚Ρ€ΠΈ Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Π½Π°ΠΌΠΈ прилоТСния. Π£ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° Π΅ΡΡ‚ΡŒ ΠΊΠ°ΠΊ прСимущСства, Ρ‚Π°ΠΊ ΠΈ нСдостатки. ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΠΈΠΌ ΠΏΠ»ΡŽΡΡ‹.

1. Экономия Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°:

  • ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π½Π΅ всС Π΄Π°Π½Π½Ρ‹Π΅, Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΡ… Ρ‡Π°ΡΡ‚ΡŒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡ… столбцы ΠΈΠ»ΠΈ записи, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ);
  • Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, которая выполняСтся Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎ Π² асинхронном (Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ вСрсии Tarantool β€” 1.10) ΠΈΠ»ΠΈ синхронном (Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π² ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… вСрсиях Tarantool) Ρ€Π΅ΠΆΠΈΠΌΠ΅, Π²Ρ‹ΡΠΎΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΡƒΡŽ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ сСансами (Ρ‚.Π΅. ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ сначала выполняСт ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ… β€” сСанс ΠΎΠ±ΠΌΠ΅Π½Π° Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, Π·Π°Ρ‚Π΅ΠΌ наступаСт ΠΏΠ°ΡƒΠ·Π° Π² Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, послС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ происходит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ сСанс ΠΎΠ±ΠΌΠ΅Π½Π° ΠΈ Ρ‚.Π΄.);
  • Ссли запись измСнилась нСсколько Ρ€Π°Π·, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΅Π΅ послСднюю Π²Π΅Ρ€ΡΠΈΡŽ (Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½Π° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ… Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ³Ρ€Π°Π½Ρ‹ всС измСнСния, сдСланныС Π½Π° мастСрС).

2. ΠžΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ слоТности с Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΎΠ±ΠΌΠ΅Π½Π° ΠΏΠΎ HTTP, Ρ‡Ρ‚ΠΎ позволяСт ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ Π‘Π”.

ВысокоуровнСвая рСпликация Π² Π‘Π£Π‘Π” Tarantool
Рис. 2. РСпликация ΠΏΠΎ HTTP

3. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ Π‘Π”, ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅, Π½Π΅ обязаны Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ (Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π² ΠΎΠ±Ρ‰Π΅ΠΌ случаС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π°ΠΆΠ΅ использованиС Ρ€Π°Π·Π½Ρ‹Ρ… Π‘Π£Π‘Π”, языков программирования, ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌ ΠΈ Ρ‚.ΠΏ.).

ВысокоуровнСвая рСпликация Π² Π‘Π£Π‘Π” Tarantool
Рис. 3. РСпликация Π² Π³Π΅Ρ‚Π΅Ρ€ΠΎΠ³Π΅Π½Π½Ρ‹Ρ… систСмах

ΠœΠΈΠ½ΡƒΡ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π² срСднСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слоТнСС/Π·Π°Ρ‚Ρ€Π°Ρ‚Π½Π΅Π΅, Ρ‡Π΅ΠΌ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΈ вмСсто настройки встроСнного Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π° придСтся Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ свой собствСнный.

Если Π² вашСй ситуации ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Π΅ ΠΏΠ»ΡŽΡΡ‹ ΠΈΠ³Ρ€Π°ΡŽΡ‚ Ρ€Π΅ΡˆΠ°ΡŽΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ (ΠΈΠ»ΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹ΠΌ условиСм), Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ‹ΡΠΎΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΡƒΡŽ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡŽ. Рассмотрим нСсколько способов Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² Π‘Π£Π‘Π” Tarantool.

ΠœΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°

Π˜Ρ‚Π°ΠΊ, ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· прСимущСств высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ являСтся экономия Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°. Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ это прСимущСство ΠΏΡ€ΠΎΡΠ²ΠΈΠ»ΠΎΡΡŒ Π² ΠΏΠΎΠ»Π½ΠΎΠΉ ΠΌΠ΅Ρ€Π΅, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ количСство Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ сСансС ΠΎΠ±ΠΌΠ΅Π½Π°. РазумССтся, ΠΏΡ€ΠΈ этом Π½Π΅ стоит Π·Π°Π±Ρ‹Π²Π°Ρ‚ΡŒ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π² ΠΊΠΎΠ½Ρ†Π΅ сСанса ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ Π΄Π°Π½Π½Ρ‹Ρ… Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ синхронизирован с источником (ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ ΠΏΠΎ Ρ‚ΠΎΠΉ части Π΄Π°Π½Π½Ρ‹Ρ…, которая участвуСт Π² Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ).

Как ΠΆΠ΅ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ количСство Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΈ высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ? РСшСниСм Β«Π² Π»ΠΎΠ±Β» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚Π±ΠΎΡ€ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ Π΄Π°Ρ‚Π΅-Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Для этого ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΆΠ΅ ΠΈΠΌΠ΅ΡŽΡ‰Π΅Π΅ΡΡ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΏΠΎΠ»Π΅ Π΄Π°Ρ‚Ρ‹-Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (Ссли ΠΎΠ½ΠΎ Π΅ΡΡ‚ΡŒ). НапримСр, Ρƒ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π° Β«Π·Π°ΠΊΠ°Π·Β» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅ Β«Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ΅ врСмя исполнСния Π·Π°ΠΊΠ°Π·Π°Β» β€” delivery_time. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ значСния Π² этом ΠΏΠΎΠ»Π΅ Π½Π΅ обязаны Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ созданию Π·Π°ΠΊΠ°Π·ΠΎΠ². Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ максимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля delivery_time, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ сСанса ΠΎΠ±ΠΌΠ΅Π½Π°, ΠΈ ΠΏΡ€ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ сСансС ΠΎΠ±ΠΌΠ΅Π½Π° ΠΎΡ‚ΠΎΠ±Ρ€Π°Ρ‚ΡŒ всС записи с Π±ΠΎΠ»Π΅Π΅ высоким Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ поля delivery_time. Π’ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ сСансами ΠΎΠ±ΠΌΠ΅Π½Π° ΠΌΠΎΠ³Π»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒΡΡ записи с мСньшим Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ поля delivery_time. Π’Π°ΠΊΠΆΠ΅ Π·Π°ΠΊΠ°Π· ΠΌΠΎΠ³ ΠΏΡ€Π΅Ρ‚Π΅Ρ€ΠΏΠ΅Ρ‚ΡŒ измСнСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ Π½Π΅ Π·Π°Ρ‚Ρ€ΠΎΠ½ΡƒΠ»ΠΈ ΠΏΠΎΠ»Π΅ delivery_time. Π’ ΠΎΠ±ΠΎΠΈΡ… случаях измСнСния Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ с источника Π² ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ. Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этих ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π°ΠΌ потрСбуСтся ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ «внахлСст». Π’.Π΅. ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ сСансС ΠΎΠ±ΠΌΠ΅Π½Π° ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ всС Π΄Π°Π½Π½Ρ‹Π΅ со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ поля delivery_time, ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π² ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, N часов ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°). Однако ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ для ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… систСм Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ являСтся сильно ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½Ρ‹ΠΌ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ свСсти экономию Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ стрСмимся, Π½Π° Π½Π΅Ρ‚. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Π² ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ Π±Ρ‹Ρ‚ΡŒ поля, связанного с Π΄Π°Ρ‚ΠΎΠΉ-Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ.

Π”Ρ€ΡƒΠ³ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, Π±ΠΎΠ»Π΅Π΅ слоТноС с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠΈ получСния Π΄Π°Π½Π½Ρ‹Ρ…. Π’ этом случаС ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ сСансС ΠΎΠ±ΠΌΠ΅Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ всС Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π»Π΅ΠΌ. Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ потрСбуСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ-источник Π±ΡƒΠ»Π΅Π²ΡΠΊΡƒΡŽ ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, is_transferred). Если ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ записи, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ ΠΏΠΎΠ»Π΅ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ true, послС Ρ‡Π΅Π³ΠΎ запись Π±ΠΎΠ»Π΅Π΅ Π½Π΅ участвуСт Π² ΠΎΠ±ΠΌΠ΅Π½Π°Ρ…. Π’Π°ΠΊΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ минусы. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠΉ записи Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅. Π“Ρ€ΡƒΠ±ΠΎ говоря, это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сопоставимо с ΡƒΠ΄Π²ΠΎΠ΅Π½ΠΈΠ΅ΠΌ количСства ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ привСсти ΠΊ ΡƒΠ΄Π²ΠΎΠ΅Π½ΠΈΡŽ количСства Ρ€Π°ΡƒΠ½Π΄Ρ‚Ρ€ΠΈΠΏΠΎΠ². Π’ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, отсутствуСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΠΎΠ΄Π½ΠΎΠΉ ΠΈ Ρ‚ΠΎΠΉ ΠΆΠ΅ записи Π² нСсколько ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠΎΠ² (ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ²ΡˆΠΈΠΉ ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π·Π° сСбя ΠΈ Π·Π° всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ…).

Бпособ, Π»ΠΈΡˆΠ΅Π½Π½Ρ‹ΠΉ нСдостатков, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Π²Ρ‹ΡˆΠ΅, состоит Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π² ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡƒΡŽ Ρ‚Π°Π±Π»ΠΈΡ†Ρƒ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ для отслСТивания ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π΅Π΅ строк. Вакая ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΈΠΏ Π΄Π°Ρ‚Π°-врСмя ΠΈ Π΄ΠΎΠ»ΠΆΠ½Π° Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒΡΡ/ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒΡΡ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π½Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ/ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ записСй (Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎ с Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ/ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ). Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π°Π·ΠΎΠ²Π΅ΠΌ ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ update_time. Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠ² максимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля этой ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ для ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… записСй, ΠΌΡ‹ смоТСм Π½Π°Ρ‡Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ сСанс ΠΎΠ±ΠΌΠ΅Π½Π° с этого значСния (ΠΎΡ‚ΠΎΠ±Ρ€Π°Ρ‚ΡŒ записи со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ поля update_time, ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°ΡŽΡ‰ΠΈΠΌ сохранСнноС Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅). ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, связанная с послСдним ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ измСнСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² ΠΏΠ°ΠΊΠ΅Ρ‚Π½ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ значСния ΠΏΠΎΠ»Π΅ΠΉ Π² ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ΅ update_time ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, эта ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована для ΠΏΠΎΡ€Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ (постраничной) Π²Ρ‹Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…. Для постраничной Π²Ρ‹Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… придСтся ΠΈΠ·ΠΎΠ±Ρ€Π΅Ρ‚Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅, скорСС всСго, Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ Π½ΠΈΠ·ΠΊΡƒΡŽ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ· Π‘Π” всСх записСй со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ update_time Π²Ρ‹ΡˆΠ΅ Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΈ Π²Ρ‹Π΄Π°Ρ‡Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ количСства записСй, начиная с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ смСщСния ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π° Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ).

МоТно ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄. Для этого Π² качСствС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΏΠΎΠ»Π΅ΠΉ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ для отслСТивания ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ цСлочислСнный Ρ‚ΠΈΠΏ (Π΄Π»ΠΈΠ½Π½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅). НазовСм ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ row_ver. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля этой ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ ΠΏΠΎ-ΠΏΡ€Π΅ΠΆΠ½Π΅ΠΌΡƒ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒΡΡ/ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒΡΡ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ создании/ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ записи. Но Π² Π΄Π°Π½Π½ΠΎΠΌ случаС полю Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π΄Π°Ρ‚Π°-врСмя, Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ счСтчика, ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° row_ver Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ значСния ΠΈ смоТСт Π±Ρ‹Ρ‚ΡŒ использована Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для Π²Ρ‹Π΄Π°Ρ‡ΠΈ Β«Π΄Π΅Π»ΡŒΡ‚Ρ‹Β» Π΄Π°Π½Π½Ρ‹Ρ… (Π΄Π°Π½Π½Ρ‹Ρ…, Π΄ΠΎΠ±Π°Π²ΠΈΠ²ΡˆΠΈΡ…ΡΡ/ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ²ΡˆΠΈΡ…ΡΡ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ сСанса ΠΎΠ±ΠΌΠ΅Π½Π°), Π½ΠΎ ΠΈ для простой ΠΈ эффСктивной Ρ€Π°Π·Π±ΠΈΠ²ΠΊΠΈ ΠΈΡ… Π½Π° страницы.

ПослСдний ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ способ ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ количСства Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π² Ρ€Π°ΠΌΠΊΠ°Ρ… высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ, прСдставляСтся ΠΌΠ½Π΅ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΌ. ΠžΡΡ‚Π°Π½ΠΎΠ²ΠΈΠΌΡΡ Π½Π° Π½Π΅ΠΌ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅.

ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π΄Π°Π½Π½Ρ‹Ρ… с использованиСм счСтчика вСрсий строк

РСализация сСрвСрной/master части

Π’ MS SQL Server для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° сущСствуСт ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ β€” rowversion. КаТдая Π‘Π” ΠΈΠΌΠ΅Π΅Ρ‚ счСтчик, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ увСличиваСтся Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ/ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ записи Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅, ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ Ρ‚ΠΈΠΏΠ° rowversion. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого счСтчика автоматичСски присваиваСтся полю этой ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ Π² добавившСйся/измСнившСйся записи. Π‘Π£Π‘Π” Tarantool Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠ³ΠΎ встроСнного ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°. Однако Π² Tarantool Π΅Π³ΠΎ нСслоТно Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. Рассмотрим, ΠΊΠ°ΠΊ это дСлаСтся.

Для Π½Π°Ρ‡Π°Π»Π° Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΠΈ: Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ Π² Tarantool Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ спСйсами (space), Π° записи β€” ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°ΠΌΠΈ (tuple). Π’ Tarantool ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ (sequence). ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΈΠ· сСбя Π½Π΅ Ρ‡Ρ‚ΠΎ ΠΈΠ½ΠΎΠ΅, ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ упорядочСнных Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ†Π΅Π»Ρ‹Ρ… чисСл. Π’.Π΅. это ΠΊΠ°ΠΊ Ρ€Π°Π· Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ для Π½Π°ΡˆΠΈΡ… Ρ†Π΅Π»Π΅ΠΉ. НиТС ΠΌΡ‹ создадим Ρ‚Π°ΠΊΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ-Π»ΠΈΠ±ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… Π² Tarantool, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

box.cfg{}

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Tarantool Π½Π°Ρ‡Π½Π΅Ρ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ Π² Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ снимки Π‘Π” (snapshot) ΠΈ ΠΆΡƒΡ€Π½Π°Π» Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ row_version:

box.schema.sequence.create('row_version',
    { if_not_exists = true })

ΠžΠΏΡ†ΠΈΡ if_not_exists позволяСт Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ скрипт создания ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ: Ссли ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ сущСствуСт, Tarantool Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ. Π­Ρ‚Π° опция Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π²ΠΎ всСх ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… DDL-ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ….

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ спСйс для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°.

box.schema.space.create('goods', {
    format = {
        {
            name = 'id',
            type = 'unsigned'

        },
        {
            name = 'name',
            type = 'string'

        },
        {
            name = 'code',
            type = 'unsigned'

        },
        {
            name = 'row_ver',
            type = 'unsigned'

        }
    },
    if_not_exists = true
})

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ Π·Π°Π΄Π°Π»ΠΈ имя спСйса (goods), ΠΈΠΌΠ΅Π½Π° ΠΏΠΎΠ»Π΅ΠΉ ΠΈ ΠΈΡ… Ρ‚ΠΈΠΏΡ‹.

АвтоинкрСмСнтныС поля Π² Tarantool ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠΆΠ΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚Π΅ΠΉ. Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π°Π²Ρ‚ΠΎΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π½Ρ‹ΠΉ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ ΠΏΠΎ полю id:

box.schema.sequence.create('goods_id',
    { if_not_exists = true })
box.space.goods:create_index('primary', {
    parts = { 'id' },
    sequence = 'goods_id',
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

Tarantool ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ нСсколько Ρ‚ΠΈΠΏΠΎΠ² индСксов. Π§Π°Ρ‰Π΅ всСго ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ индСксы Ρ‚ΠΈΠΏΠΎΠ² TREE ΠΈ HASH, Π² основС ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π»Π΅ΠΆΠ°Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ наимСнованию структуры. TREE β€” Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ индСкса. Он позволяСт ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² упорядочСнном Π²ΠΈΠ΄Π΅. Но для Π²Ρ‹Π±ΠΎΡ€Π° ΠΏΠΎ равСнству большС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ HASH. БоотвСтствСнно, для ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° цСлСсообразно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ HASH (Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈ сдСлали).

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ»ΠΎΠ½ΠΊΡƒ row_ver для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ²ΡˆΠΈΡ…ΡΡ Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΈΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΊ полям этой ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ значСния ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ row_ver. Но Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠΈ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ row_ver Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒΡΡ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½ΠΎΠ²Ρ‹Ρ… записСй, Π½ΠΎ ΠΈ ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ…. Для этого ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹. Π’ Tarantool Π΅ΡΡ‚ΡŒ Π΄Π²Π° Ρ‚ΠΈΠΏΠ° Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΎΠ² для спСйсов: before_replace ΠΈ on_replace. Π’Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² спСйсС (для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°, Π·Π°Ρ‚Ρ€ΠΎΠ½ΡƒΡ‚ΠΎΠ³ΠΎ измСнСниями, запускаСтся функция Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Π°). Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ on_replace, before_replace-Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ выполняСтся Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€. БоотвСтствСнно, Π½Π°ΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ послСдний Ρ‚ΠΈΠΏ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΎΠ².

box.space.goods:before_replace(function(old, new)
    return box.tuple.new({new[1], new[2], new[3],
        box.sequence.row_version:next()})
end)

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ замСняСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля row_ver сохраняСмого ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ° Π½Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ row_version.

Для Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· спСйса goods ΠΏΠΎ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ΅ row_ver, создадим индСкс:

box.space.goods:create_index('row_ver', {
    parts = { 'row_ver' },
    unique = true,
    type = 'TREE',
    if_not_exists = true
})

Π’ΠΈΠΏ индСкса β€” Π΄Π΅Ρ€Π΅Π²ΠΎ (TREE), Ρ‚.ΠΊ. Π΄Π°Π½Π½Ρ‹Π΅ Π½Π°ΠΌ потрСбуСтся ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ Π² порядкС возрастания Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ΅ row_ver.

Π”ΠΎΠ±Π°Π²ΠΈΠΌ Π² спСйс Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅:

box.space.goods:insert{nil, 'pen', 123}
box.space.goods:insert{nil, 'pencil', 321}
box.space.goods:insert{nil, 'brush', 100}
box.space.goods:insert{nil, 'watercolour', 456}
box.space.goods:insert{nil, 'album', 101}
box.space.goods:insert{nil, 'notebook', 800}
box.space.goods:insert{nil, 'rubber', 531}
box.space.goods:insert{nil, 'ruler', 135}

Π’.ΠΊ. ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΏΠΎΠ»Π΅ β€” Π°Π²Ρ‚ΠΎΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π½Ρ‹ΠΉ счСтчик, ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ вмСсто Π½Π΅Π³ΠΎ nil. Tarantool автоматичСски подставит ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Аналогичным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π² качСствС значСния ΠΏΠΎΠ»Π΅ΠΉ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠΈ row_ver ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ nil β€” ΠΈΠ»ΠΈ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²ΠΎΠΎΠ±Ρ‰Π΅, Ρ‚.ΠΊ. эта ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ послСднюю ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π² спСйсС.

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ вставки:

tarantool> box.space.goods:select()
---
- - [1, 'pen', 123, 1]
  - [2, 'pencil', 321, 2]
  - [3, 'brush', 100, 3]
  - [4, 'watercolour', 456, 4]
  - [5, 'album', 101, 5]
  - [6, 'notebook', 800, 6]
  - [7, 'rubber', 531, 7]
  - [8, 'ruler', 135, 8]
...

Как Π²ΠΈΠ΄ΠΈΠΌ, ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΈ послСднСС ΠΏΠΎΠ»Π΅ заполнились автоматичСски. Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π±ΡƒΠ΄Π΅Ρ‚ нСслоТно Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для постраничной Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ спСйса goods:

local page_size = 5
local function get_goods(row_ver)
    local index = box.space.goods.index.row_ver
    local goods = {}
    local counter = 0
    for _, tuple in index:pairs(row_ver, {
        iterator = 'GT' }) do
        local obj = tuple:tomap({ names_only = true })
        table.insert(goods, obj)
        counter = counter + 1
        if counter >= page_size then
            break
        end
    end
    return goods
end

Ѐункция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ row_ver, начиная с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΡƒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ, ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΏΠΎΡ€Ρ†ΠΈΡŽ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ²ΡˆΠΈΡ…ΡΡ Π΄Π°Π½Π½Ρ‹Ρ….

Π’Ρ‹Π±ΠΎΡ€ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… Π² Tarantool производится Ρ‡Π΅Ρ€Π΅Π· индСксы. Ѐункция get_goods ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΏΠΎ индСксу row_ver для получСния ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ²ΡˆΠΈΡ…ΡΡ Π΄Π°Π½Π½Ρ‹Ρ…. Π’ΠΈΠΏ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° β€” GT (Greater Than, большС Ρ‡Π΅ΠΌ). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±Ρ…ΠΎΠ΄ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ индСкса начиная с ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° (значСния поля row_ver).

Π˜Ρ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ впослСдствии ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ HTTP, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ΠΉ ΠΊ структурС, ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ для ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ сСриализации. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ стандартная функция tomap. ВмСсто использования tomap ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. НапримСр, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Ρ…ΠΎΡ‚Π΅Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π΅ name, Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π΅ code ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΠ»Π΅ comment:

local function unflatten_goods(tuple)
    local obj = {}
    obj.id = tuple.id
    obj.goods_name = tuple.name
    obj.comment = 'some comment'
    obj.row_ver = tuple.row_ver
    return obj
end

Π Π°Π·ΠΌΠ΅Ρ€ страницы Π²Ρ‹Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… (количСство записСй Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡ€Ρ†ΠΈΠΈ) опрСдСляСтся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ page_size. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ page_size Ρ€Π°Π²Π½ΠΎ 5. Π’ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€ страницы ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ большСС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Он зависит ΠΎΡ‚ срСднСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ° спСйса. ΠžΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ страницы ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹ΠΌ ΠΏΡƒΡ‚Π΅ΠΌ, замСряя врСмя ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…. Π§Π΅ΠΌ большС Ρ€Π°Π·ΠΌΠ΅Ρ€ страницы, Ρ‚Π΅ΠΌ мСньшС количСство Ρ€Π°ΡƒΠ½Π΄Ρ‚Ρ€ΠΈΠΏΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‰Π΅ΠΉ ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ стороной. Π’Π°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ ΠΎΠ±Ρ‰Π΅Π΅ врСмя Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ. Однако ΠΏΡ€ΠΈ слишком большом Ρ€Π°Π·ΠΌΠ΅Ρ€Π΅ страницы ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ слишком Π΄ΠΎΠ»Π³ΠΎ Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒ сСрвСр сСриализациСй Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡƒΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… запросов, ΠΏΡ€ΠΈΡˆΠ΅Π΄ΡˆΠΈΡ… Π½Π° сСрвСр. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ page_size ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ ΠΈΠ· ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ спСйса ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ своС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. ΠŸΡ€ΠΈ этом для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° спСйсов ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ΄ΠΎΠΉΡ‚ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, 100).

Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ get_goods:

tarantool> get_goods(0)

---
- - row_ver: 1
    code: 123
    name: pen
    id: 1
  - row_ver: 2
    code: 321
    name: pencil
    id: 2
  - row_ver: 3
    code: 100
    name: brush
    id: 3
  - row_ver: 4
    code: 456
    name: watercolour
    id: 4
  - row_ver: 5
    code: 101
    name: album
    id: 5
...

Π’ΠΎΠ·ΡŒΠΌΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля row_ver ΠΈΠ· послСднСй строки ΠΈ вновь Π²Ρ‹Π·ΠΎΠ²Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

tarantool> get_goods(5)

---
- - row_ver: 6
    code: 800
    name: notebook
    id: 6
  - row_ver: 7
    code: 531
    name: rubber
    id: 7
  - row_ver: 8
    code: 135
    name: ruler
    id: 8
...

И Π΅Ρ‰Π΅ Ρ€Π°Π·:

tarantool> get_goods(8)
---
- []
...

Как Π²ΠΈΠ΄ΠΈΠΌ, ΠΏΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ использовании функция постранично Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ всС записи спСйса goods. Π—Π° послСднСй страницСй слСдуСт пустая Π²Ρ‹Π±ΠΎΡ€ΠΊΠ°.

ВнСсСм измСнСния Π² спСйс:

box.space.goods:update(4, {{'=', 6, 'copybook'}})
box.space.goods:insert{nil, 'clip', 234}
box.space.goods:insert{nil, 'folder', 432}

ΠœΡ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля name для ΠΎΠ΄Π½ΠΎΠΉ записи ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π΄Π²Π΅ Π½ΠΎΠ²Ρ‹Ρ… записи.

ΠŸΠΎΠ²Ρ‚ΠΎΡ€ΠΈΠΌ послСдний Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

tarantool> get_goods(8)
---



- - row_ver: 9
    code: 800
    name: copybook
    id: 6
  - row_ver: 10
    code: 234
    name: clip
    id: 9
  - row_ver: 11
    code: 432
    name: folder
    id: 10
...

Ѐункция Π²Π΅Ρ€Π½ΡƒΠ»Π° ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ²ΡˆΡƒΡŽΡΡ ΠΈ добавившиСся записи. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, функция get_goods позволяСт ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, измСнившиСся с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π΅Π΅ послСднСго Π²Ρ‹Π·ΠΎΠ²Π°, Ρ‡Ρ‚ΠΎ ΠΈ являСтся основой рассматриваСмого способа Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ.

ΠžΡΡ‚Π°Π²ΠΈΠΌ Π²Ρ‹Π΄Π°Ρ‡Ρƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΏΠΎ HTTP Π² Π²ΠΈΠ΄Π΅ JSON Π·Π° Ρ€Π°ΠΌΠΊΠ°ΠΌΠΈ настоящСй ΡΡ‚Π°Ρ‚ΡŒΠΈ. Об этом ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ здСсь: https://habr.com/ru/company/mailru/blog/272141/

РСализация клиСнтской/slave части

Рассмотрим, ΠΊΠ°ΠΊ выглядит рСализация ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ стороны. Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰Π΅ΠΉ сторонС спСйс для хранСния Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…:

box.schema.space.create('goods', {
    format = {
        {
            name = 'id',
            type = 'unsigned'

        },
        {
            name = 'name',
            type = 'string'

        },
        {
            name = 'code',
            type = 'unsigned'

        }
    },
    if_not_exists = true
})

box.space.goods:create_index('primary', {
    parts = { 'id' },
    sequence = 'goods_id',
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° спСйса Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ структуру спСйса Π² источникС. Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π½Π΅ собираСмся ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΡƒΠ΄Π°-Π»ΠΈΠ±ΠΎ Π΅Ρ‰Π΅, ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° row_ver Π² спСйсС получатСля отсутствуСт. Π’ ΠΏΠΎΠ»Π΅ id Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒΡΡ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ источника. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π½Π° сторонС ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠ° Π½Π΅Ρ‚ нСобходимости Π΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π°Π²Ρ‚ΠΎΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π½Ρ‹ΠΌ.

ΠšΡ€ΠΎΠΌΠ΅ этого, Π½Π°ΠΌ потрСбуСтся спСйс для сохранСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ row_ver:

box.schema.space.create('row_ver', {
    format = {
        {
            name = 'space_name',
            type = 'string'

        },
        {
            name = 'value',
            type = 'string'

        }
    },
    if_not_exists = true
})

box.space.row_ver:create_index('primary', {
    parts = { 'space_name' },
    unique = true,
    type = 'HASH',
    if_not_exists = true
})

Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ спСйса (ΠΏΠΎΠ»Π΅ space_name) Π±ΡƒΠ΄Π΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ здСсь послСднСС Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ row_ver (ΠΏΠΎΠ»Π΅ value). Π’ качСствС ΠΏΠ΅Ρ€Π²ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π° выступаСт ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ° space_name.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… спСйса goods ΠΏΠΎ HTTP. Для этого Π½Π°ΠΌ потрСбуСтся Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰Π°Ρ HTTP-ΠΊΠ»ΠΈΠ΅Π½Ρ‚. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ строка Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ ΠΈ создаСт экзСмпляр HTTP-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:

local http_client = require('http.client').new()

Π’Π°ΠΊΠΆΠ΅ Π½Π°ΠΌ потрСбуСтся Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для дСсСриализации json:

local json = require('json')

Π­Ρ‚ΠΎΠ³ΠΎ достаточно для создания Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ…:

local function load_data(url, row_ver)
    local url = ('%s?rowVer=%s'):format(url,
        tostring(row_ver))
    local body = nil
    local data = http_client:request('GET', url, body, {
        keepalive_idle =  1,
        keepalive_interval = 1
    })
    return json.decode(data.body)
end

Ѐункция выполняСт HTTP-запрос ΠΏΠΎ адрСсу url, ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Π² Π½Π΅Π³ΠΎ row_ver Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ дСсСриализованный Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ запроса.

Ѐункция сохранСния ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… выглядит ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

local function save_goods(goods)
    local n = #goods
    box.atomic(function()
        for i = 1, n do
            local obj = goods[i]
            box.space.goods:put(
                obj.id, obj.name, obj.code)
        end
    end)
end

Π¦ΠΈΠΊΠ» сохранСния Π΄Π°Π½Π½Ρ‹Ρ… Π² спСйс goods ΠΏΠΎΠΌΠ΅Ρ‰Π΅Π½ Π² Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΡŽ (для этого ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ функция box.atomic) для ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ количСства ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ с диском.

НаконСц, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ синхронизации локального спСйса goods с источником ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

local function sync_goods()
    local tuple = box.space.row_ver:get('goods')
    local row_ver = tuple and tuple.value or 0

    β€”β€” set your url here:
    local url = 'http://127.0.0.1:81/test/goods/list'

    while true do
        local goods = load_goods(url, row_ver)

        local count = #goods
        if count == 0 then
            return
        end

        save_goods(goods)

        row_ver = goods[count].rowVer
        box.space.row_ver:put({'goods', row_ver})
    end
end

Π‘Π½Π°Ρ‡Π°Π»Π° считываСм сохранСнноС Ρ€Π°Π½Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ row_ver для спСйса goods. Если ΠΎΠ½ΠΎ отсутствуСт (ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ сСанс ΠΎΠ±ΠΌΠ΅Π½Π°), Ρ‚ΠΎ Π±Π΅Ρ€Π΅ΠΌ Π² качСствС row_ver ноль. Π”Π°Π»Π΅Π΅ Π² Ρ†ΠΈΠΊΠ»Π΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ ΠΏΠΎΡΡ‚Ρ€Π°Π½ΠΈΡ‡Π½ΡƒΡŽ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠ· источника ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ url. На ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ сохраняСм ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ спСйс ΠΈ обновляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ row_ver (Π² спСйсС row_ver ΠΈ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ row_ver) β€” Π±Π΅Ρ€Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ row_ver ΠΈΠ· послСднСй строки Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ….

Для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ случайного зацикливания (Π² случаС ошибки Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅) Ρ†ΠΈΠΊΠ» while ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π° for:

for _ = 1, max_req do ...

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sync_goods спСйс goods Π² ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ послСдниС вСрсии всСх записСй спСйса goods Π² источникС.

ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΠΌ способом нСльзя Ρ‚Ρ€Π°Π½ΡΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…. Если такая Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ сущСствуСт, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠΌΠ΅Ρ‚ΠΊΡƒ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅. ДобавляСм Π² спСйс goods булСвскоС ΠΏΠΎΠ»Π΅ is_deleted ΠΈ вмСсто физичСского удалСния записи ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ логичСскоС ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ β€” выставляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ поля is_deleted Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ true. Иногда вмСсто булСвского поля is_deleted ΡƒΠ΄ΠΎΠ±Π½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π΅ deleted, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ хранится Π΄Π°Ρ‚Π°-врСмя логичСского удалСния записи. ПослС выполнСния логичСского удалСния помСчСнная Π½Π° ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ запись Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° ΠΈΠ· источника Π² ΠΏΡ€ΠΈΠ΅ΠΌΠ½ΠΈΠΊ (согласно рассмотрСнной Π²Ρ‹ΡˆΠ΅ Π»ΠΎΠ³ΠΈΠΊΠ΅).

ΠŸΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ row_ver ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π΄Ρ€ΡƒΠ³ΠΈΡ… спСйсов: Π½Π΅Ρ‚ нСобходимости Π² создании ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ спСйса.

ΠœΡ‹ рассмотрСли эффСктивный способ высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² прилоТСниях, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… Π‘Π£Π‘Π” Tarantool.

Π’Ρ‹Π²ΠΎΠ΄Ρ‹

  1. Π‘Π£Π‘Π” Tarantool β€” ΠΏΡ€ΠΈΠ²Π»Π΅ΠΊΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ, пСрспСктивный ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ для создания высоконагруТСнных ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.
  2. ВысокоуровнСвая рСпликация Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΠΌΠ΅Π΅Ρ‚ ряд прСимущСств ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΉ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ.
  3. РассмотрСнный Π² ΡΡ‚Π°Ρ‚ΡŒΠ΅ способ высокоуровнСвой Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ позволяСт ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ количСство ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΡƒΡ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅Ρ… записСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ измСнились послС послСднСго сСанса ΠΎΠ±ΠΌΠ΅Π½Π°.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ