kvs_annnounce.htm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. <!DOCTYPE html><html><head><meta charset="utf-8" /><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="description" content="" /><meta name="author" content="Maxim Sokhatsky" /><title>Нова версія KVS</title><link rel="stylesheet" href="https://forms.n2o.space/priv/static/css/forms.css?v=1" /><link rel="stylesheet" href="https://tonpa.guru/blank.css?v=2" /></head><body><nav>
  2. <a href="https://n2o.dev/ua/">DEV</a>
  3. <a href="index.html">KVS</a>
  4. <a href="#" style="background:#ededed;">АНОНС</a>
  5. </nav><main>
  6. <section>
  7. <h3>Нова версія KVS 6.4</h3>
  8. <p>KVS — слой абстракції, який складається з двох частин: базового API та API керування стрімами,
  9. тейк, дроп, фолд, катаморфізм, як ви любите. Головний API в модулі kvs,
  10. а стрімовий — в kvs_stream. Користуючись нагодою, хочу пропіарити схожі рішення
  11. в області зберігання даних на erlang: <a href="https://github.com/fogfish/datum">datum</a> та серія бібліотек
  12. від Дмитра Колесникова, <a href="https://github.com/emqx/replayq">replayq</a> від Фенга Лі,
  13. а також небагатьох інших, хто намагався абстрактно вирішити проблему.</p>
  14. <h3>Чому KVS?</h3>
  15. <p>Призначення KVS:</p>
  16. <p>— надання інтерфейсу абстрагування широкого спектра сховищ;<br />
  17. — надання зручного Erlang REPL інтерфейсу для роботи з записами (records);<br />
  18. — розділення на базовий (get put) інтерфейс, та стрім інтерфейс ітераторів (next prev);<br />
  19. — набір драйверів (внутрішня база, зовнішня база і файлова система);<br />
  20. — шари даних: файлова система, ланцюжки повідомлень, банківські транзакції, дерева
  21. підписів, трейси бізнес-процесів, блокчейни, системи черг,
  22. тайм серіес, ось це все.<br />
  23. </p>
  24. <p>Розпочинаючи з незначної модифікації KVS поміняла назву, тепер це "Абстрактна База Ланцюжків",
  25. а не "Абстрактна База Термів", оскільки відділився окремий стрім API.</p>
  26. <p>— <a href="https://github.com/synrc/kvs">synrc/kvs</a> — 6.4<br /></p>
  27. <p> Розповімо трохи про теоретичні основи KVS. Ця бібліотека дозволяє або повинна
  28. дозволяти зберігати та діставати структури будь-якого виду, надаючи семантику управління
  29. курсорами next prev, якою володіють дерева. Тому можна сказати, що це інтерфейс
  30. оператора до деревоподібних сховищ та сховищ ланцюжків. У своїй основі KVS підтримує три
  31. механізми зберігання ланцюжків:</p>
  32. <p>1) перший, очевидний — двонаправлені списки, де вказівники next та prev
  33. безпосереднім чином присутні в даних. Спосіб підходить
  34. навіть для керування деревами;</p>
  35. <p>2) другий, очевидний — однонаправлені списки, де наявний тільки вказівник next. Цей спосіб підходить для списків.
  36. Багато людей запитують про цей спосіб, але ми його ніколи не використовували,
  37. тому немає імплементації;</p>
  38. <p>3) третій, неочевидний спосіб — пряме вбудовувавання записів в BTree index,
  39. zero-overhead.</p>
  40. <p>В якомусь сенсі перший та другий способи реалізують певний шар поверх KVS,
  41. оскільки kvs_stream працює з будь-якими стораджами поліморфно, а ось kvs_st драйвер
  42. стрімів зроблений спеціально для rocksdb.</p>
  43. <h3>Дерева</h3>
  44. <p>Двонаправлені списки або дерева, перша модель, яка лягає прямо з С++ класів, при вивченні програмування —
  45. це зберігати в базі прямі вказівники, така система зберігання може використовуватися навіть,
  46. якщо integer поміняти на pid, тоді можна буде точково відновлювати історію виклику.</p>
  47. <figure>
  48. <code>
  49. -record(iter, { id = [] :: [] | integer(),
  50. next = [] :: [] | integer(),
  51. prev = [] :: [] | integer() } ).
  52. </code>
  53. </figure>
  54. <p>Перше поле будь-якої таблиці — це її ім'я, друге — id, третє та
  55. четверте — next і prev (сигнатура бінарного розгалуження).
  56. Поліморфно за цими зміщеннями ми очікуємо наявність цих полів
  57. для лінковки даних в ланцюжки.
  58. Базова частина разом називається #iter.</p>
  59. <h4>kvs_stream — <b>#iter{}</b></h4>
  60. <p> За поліморфое явне управління application level полями next prev рекорда #iter
  61. відповідає модуль kvs_stream. Наприклад, файловая система не надає управління
  62. своїми курсорами, тому імплементація fs вимагає наявності полів лінковки.</p>
  63. <h3>Списки</h3>
  64. <p>Однонаправлені списки, чи просто списки, це друга модель. Все таке ж, тільки без повернення назад.
  65. Не підтримується пока жодною версією KVS.</p>
  66. <figure>
  67. <code>
  68. -record(ite, { id = [] :: [] | integer(),
  69. next = [] :: [] | integer() } ).
  70. </code>
  71. </figure>
  72. <h4>kvs_stre — <b>#ite{}</b></h4>
  73. <p>Цей модуль не реалізовано, і запис не специфікований.</p>
  74. <h3>Вбудовування в індекс</h3>
  75. <p>Третя модель представляє собою прямий, більш ефективний спосіб вбудовування простору бізнес-об'єктів
  76. в простір ключів розташованої нижче таблиці, і передача управління курсорами BTree таблиці
  77. відразу в драйвер, а не в ручний link walking, як це було в riak.
  78. Базова частина поліморфних записів складається тільки з імені таблиці
  79. та id, і має назву #it. Ця модель використовується в rocksdb бекенді, який з'явився у 6.4.</p>
  80. <figure>
  81. <code>
  82. -record(it, { id = [] :: [] | integer() } ).
  83. </code>
  84. </figure>
  85. <p>Таким чином, ми можемо емулювати таблиці, в рамках єдиного простору ключів,
  86. додаючи їх як префікси до ключа (little endian), який буде автоматично
  87. відображатись в головному BTree дереві, також в цьому просторі ви можете
  88. зберігати і фіди (стріми), наприклад, топіки: <b>/p2p/maxim/doxtop</b>.
  89. Це вимагає спеціальної модифікації kvs_st для работи з записом #it,
  90. на відміну від двонаправленого #iter, який працює з драйвером kvs_stream.</p>
  91. <h4>kvs_st — <b>#it{}</b></h4>
  92. <p>За керування курсорами по ітератору бази даних відповідає модуль kvs_st.</p>
  93. <h3>На прикладі</h3>
  94. <p>Код, який показує головну ідею, на прикладі драйвера rocksdb:</p>
  95. <figure>
  96. <code>
  97. 1> {ok,Ref} = rocksdb:open("hey",[{create_if_missing,true}]).
  98. 2> rocksdb:put(Ref, &lt;&lt;"/users/1">>,&lt;&lt;"maxim">>,[{sync,true}]).
  99. 3> rocksdb:put(Ref, &lt;&lt;"/users/2">>,&lt;&lt;"doxtop">>,[{sync,true}]).
  100. 4> rocksdb:put(Ref, &lt;&lt;"/users/3">>,&lt;&lt;"vlad">>,[{sync,true}]).
  101. 5> rocksdb:put(Ref, &lt;&lt;"/staff/1">>,&lt;&lt;"vlad">>,[{sync,true}]).
  102. 6> rocksdb:put(Ref, &lt;&lt;"/staff/2">>,&lt;&lt;"maxim">>,[{sync,true}]).
  103. 7> rocksdb:put(Ref, &lt;&lt;"/staff/3">>,&lt;&lt;"doxtop">>,[{sync,true}]).
  104. 8> {ok,I} = rocksdb:iterator(Ref,[]).
  105. 9> rocksdb:iterator_move(I,{seek,&lt;&lt;"/staff/">>}).
  106. 10> rocksdb:iterator_move(I,next).
  107. 11> rocksdb:iterator_move(I,next).
  108. 12> rocksdb:iterator_move(I,next).
  109. 13> rocksdb:iterator_move(I,{seek,&lt;&lt;"/users/">>}).
  110. 14> rocksdb:iterator_move(I,next).
  111. 15> rocksdb:iterator_move(I,next).
  112. 16> rocksdb:iterator_move(I,next).
  113. </code>
  114. </figure>
  115. <h3>KVS REPL</h3>
  116. <p>Тепер, щоб зробити те ж саме на KVS, ви можете зробити просто:</p>
  117. <figure>
  118. <code>
  119. 1> kvs:ver().
  120. {version,"KVS ROCKSDB"}
  121. 2> rr(kvs).
  122. [emails,id_seq,it,iter,kvs,reader,schema,table,writer]
  123. 3> kvs:join().
  124. ok
  125. 4> kvs:put(#emails{id=1,email="maxim"}).
  126. 5> kvs:put(#emails{id=2,email="doxtop"}).
  127. 6> kvs:put(#writer{id=2}).
  128. 7> kvs:put(#writer{id=1}).
  129. 8> kvs:all(writer).
  130. [#writer{id = 1,count = 0,cache = [],args = [],first = []},
  131. #writer{id = 2,count = 0,cache = [],args = [],first = []}]
  132. 9> kvs:all(emails).
  133. [#emails{id = 1,next = [],prev = [],email = "maxim"},
  134. #emails{id = 2,next = [],prev = [],email = "doxtop"}]
  135. 10> kvs:add(#writer{id=chain,args=#emails{email="maxim@synrc.com"}}).
  136. 11> kvs:add(#writer{id=chain,args=#emails{email="vlad@synrc.com"}}).
  137. 12> kvs:add(#writer{id=chain,args=#emails{email="doxtop@synrc.com"}}).
  138. 13> kvs:all(chain).
  139. [#emails{id = 1555244691729330000,next = [],prev = [],
  140. email = "maxim@synrc.com"},
  141. #emails{id = 1555244699905648000,next = [],prev = [],
  142. email = "doxtop@synrc.com"},
  143. #emails{id = 1555244696660271000,next = [],prev = [],
  144. email = "vlad@synrc.com"}]
  145. </code>
  146. </figure>
  147. <p>Єдиний тест на стріми, який проходить:</p>
  148. <figure>
  149. <code>
  150. > kvs:check().
  151. ok
  152. </code>
  153. </figure>
  154. <h3>Документація</h3>
  155. <p>Надіюсь зробити цю рубрику в release notes офіційною та регулярною,
  156. на жаль, якщо не брать до уваги man сторінки для модулій драйверів,
  157. то залишається лише два модулі, для яких потрібна документація — це <a href="https://kvs.n2o.space/man/kvs.htm">kvs</a> та <a href="https://kvs.n2o.space/man/kvs_stream.htm">kvs_stream</a>.
  158. Я, звичайно, формально додав сторінки для всіх модулів, і в майбутньому хочеться,
  159. щоб штучний інтелект генерував документацію. Також я зрозумів, що
  160. ченджлог та реліз замітки у власному блозі є чудовим способом авторського анонсування!
  161. Зробив історію таких сторінок в README.md.</p>
  162. <h3>На закінчення</h3>
  163. <p>Репозиторій (що депендить <a href="https://gitlab.com/barrel-db/erlang-rocksdb">rocksdb NIF драйвер</a>, який повільно компілюється,
  164. від Бенуа Кісенау, <a href="https://github.com/Vonmo/rocker">Rust-версію Rocker</a> від Максима Молчанова вирішив відкласти,
  165. надто часто раст оновлюється, неможливо зафрізити)
  166. одразу включає файл конфігурації для rocksdb:</p>
  167. <p>— <a href="https://github.com/voxoz/kv">voxoz/kv</a></p>
  168. <p>P.S. Вбудовування в BTree можна застосовувати не лише в таких базах, як rocksdb,
  169. але й для mnesia, і для будь-яких баз взагалі.</p>
  170. <p>P.P.S. Також можна використовувати rocksdb у якості драйвера для mnesia (написаний
  171. Ульфом Вігером для проекта Аетерніті), або скоріше різновид таблиці rocksdb_copies —
  172. <a href="https://github.com/aeternity/mnesia_rocksdb">mnesia_rocksdb</a>.</p>
  173. </section>
  174. </main><footer>Namdak Tonpa <span class="heart">&#160;❤&#160;</span> 2009—2019</footer></body></html>