Документиране на експеримент, при който тествах две реализации на база данни ключ-стойност, едната беше моя, а другата идваше от GPT-3.5

Прекарах доста време в разработването на база данни ключ-стойност, подкрепена от Дърво за сливане на структура на журнал (LSM дърво). За първи път се натъкнах на структурата на данните, докато четях „Глава 3 на Проектиране на приложения с интензивно използване на данни“ и за всеки, който се интересува да научи за LSM, това е най-добрата справка, която мога да ви дам. Въпреки това, не е нужно да знаете за LSM или вътрешна работа на база данни, за да прочетете този блог.

Спецификации на базата данни(за подробни спецификации вижте това)

  1. База данни ключ-стойност с две операции — вмъкване и извличане.
  2. Базата данни трябва да разкрие HTTP API за двете поддържани операции.
  3. Вмъкването трябва да се поддържа чрез
    PUT /element/:id/timestamp/:timestamp
    Къдетоid е ключ, стойността, съответстваща на ключа, се приема като тяло на заявката, очаквано във формат JSON, времево клеймо се отнася до времево клеймо на стойността за ключа.
  4. Извличането на данни за ключ трябва да се поддържа чрез
    GET /latest/element/:id
  5. За заявка за вмъкване, ако стойност за ключа вече съществува в базата данни, от двете стойности (една, получена в тялото на заявката и една вече в базата данни), трябва да се запази стойност с по-скорошен времеви печат.

Разлики в изпълнението (и прилики)

Пиша този блог, като имам предвид сравнително широка аудитория, така че споменавам само избор на много високо ниво на внедряване. Ще публикувам отделна поредица от блогове, фокусирани конкретно върху внедряването.

  1. В структурата на данните в паметта:
    И двете реализации използват карти за съхраняване на данни
    Реализацията на ChatGPT поддържа карта за ключ, която съхранява всички получени стойности досега за ключ и отделна карта на ключовете срещу клеймото за време на последната получена досега стойност.
    — Използвам изпълнение на LSM дърво, което поддържа максимум две подредени карти за всички данни, съхранени в паметта, сортирани по ключове. Техническата терминология за тези карти е Memtable(променлива структура от данни в паметта, използвана за натрупване на данни).
  2. Структура на данни за постоянство (на диск):
    Внедряването на ChatGPT е почти напълно в паметта с „кука за изключване“, която ще запази файл за ключ в случай на неочаквано прекратяване. Файлът за ключ съдържа списък на всички получени досега стойности срещу този ключ, разделени с нови редове.
    — Реализацията на LSM записва Memtableкато Сортирана таблица с низовеизвестна още като SSTable (на дискови неизменни файлове, които съхраняват данни в memtable).
  3. Възстановяване при срив:
    ChatGPT имплементира „кука за изключване“, която ще изхвърли данните от паметта на диска в случай на срив.
    — Използвах „дневник за запис напред“ .
  4. Уеб рамка (тъй като базата данни има HTTP API):
    И двете реализации са в JAVA. Изборът на уеб рамка всъщност има значително влияние върху производителността на базата данни, тъй като влияе върху начина, по който се обработват заявките.
    ChatGPT използва Spark (различно от Apache Spark само за информация).
    — Използвах VertX.

Вмъкване на потоци от двете бази данни(За изображения с по-висока разделителна способност вижте miro)

Данни за пътуване с такси в Ню Йорк

Комисията за таксита и лимузини (TLC) в Ню Йорк (NYC) пази данни от всички свои таксита. Наборът от данни се състои от над 3 милиарда пътувания с таксита и превозни средства под наем (Uber, Lyft и др.), произхождащи от Ню Йорк от 2009 г. насам, и е свободно достъпен за изтегляне от неговия „официален уебсайт“.

Записите включват полета, записващи дати/часове на качване и връщане, места за качване и връщане, разстояния за пътуване, тарифи по детайли, типове тарифи, видове плащания и брой пътници, докладван от водача.

Това е много популярен висококачествен набор от данни, който често се използва за експерименти с машинно обучение и инженеринг на данни, а също и за маркиране на бази данни. Ще включа някои полезни справки в раздела за справки на този блог.

„Състезание за детска площадка на Kaggle“ е домакин на много по-малка версия на набора от данни NYC TLC Trips, който използвах за този експеримент.

Наблюдения при пътуване с такси: Проблем за тестване

Наборът от данни е такъв, че за всяко пътуване с такси данните се изпращат до сървъра от превозно средство след края на пътуването. Така че това на практика означава, че ще има един запис на пътуване.

Какво става, ако вместо да изпраща данните след пътуването, превозното средство предава данни към сървъра всяка минута (или на някаква периодична честота), докато пътуването е в ход?
Нека наречем тези данни наблюдения на пътуването.Записът за наблюдение на пътуването включва всички същите полета като записа на пътуването, само че допълнително включва текущите координати на местоположението на превозно средство с времево клеймо, когато пътуването е в ход.

Генерирах синтетичен набор от данни за наблюдения на пътувания, използвайки PySpark за тестване на базите данни. За подробности вижте „хранилище GitHub за генериране на синтетични данни“.

Ето „примерен CSV с наблюдения на пътуването“.

Сега, когато има множество записи за пътуване, наборът от данни за наблюдения на пътувания може да се използва за тестване на коректността на базите данни ключ-стойност.

Ето как го направих:

  1. Използвах Trip idкато ключ и trip observation като стойност, така че във всеки момент за даден идентификатор на пътуване базата данни трябва да върне най-новото наблюдение, което е получила досега.
  2. Всяко пътуване има множество наблюдения и всяко наблюдение има клеймо за време, което определя неговия ред.
  3. Вмъкнах нередовни наблюдения в базата данни, която се тества, т.е. наблюденията за едно пътуване не се вмъкват непременно по реда на тяхното времево клеймо.
  4. След това, след като всички вмъквания приключат, проверих дали базата данни е съхранила наблюдението с най-новото времево клеймо за всяко пътуване или не.
  5. Първо направих този тест с шепа наблюдения, отнасящи се до няколко пътувания и както се очакваше и двете бази данни преминаха този тест.
  6. След това повторих този тест с ~300K наблюдения, които се отнасят за ~25000 пътувания, така че коректността на базите данни се тества при натоварване като изчерпателен тест.
  7. Проведох друг тест само за да тествам производителността на запис на базите данни чрез вмъкване на ~100k наблюдения за ~3,5 минути.
  8. Те са предназначени за писане на тежки бази данни, така че все още не съм правил много тестове за производителността на четене, но ще актуализирам този блог, в случай че го направя.

За провеждане на гореспоменатите (и повече) тестове използвам Gatling , за повече подробности и, разбира се, код за проверка на всички тестове тестване на производителността на базата данни ключ-стойност GitHub repository.

Резултати от тестовете

Тест 1: Тестване на коректността и ефективността — Вмъкване на 323k наблюдения за 25k уникални пътувания за 30 минути.
За този тест използвах контейнер с 256 MB основна памет и 2 процесора, имаше 8 GB дисково пространство, но дисковото пространство няма особено значение за тези тестове.

ChatGPT DB —Тъй като тази реализация беше до голяма степен карта в паметта с кеш в паметта, както се очакваше, паметта й изтече, щеше да има нужда от около 3 пъти повече основна памет, за да може да обработва тези много заявки и следователно в този случай не може да се изготви отчет на Gatling.

LSMDB — LSM изхвърля memtables на диска, така че лесно успя да се справи с това натоварване с пиково използване на паметта от ~ 60%. („връзка към доклада на Gatling“)

Тест 2: Тестване на производителността при запис — Вмъкване на 100 000 наблюдения за 200 секунди, така че натоварването на заявката за запис е ~500 req/sec за 200 секунди.
За този тест използвах контейнер с 1 GB основна памет и 4 процесора.

ChatGPT DB —Този път базата данни не се срина, но всъщност не издържа теста. Едва успя да се справи с 40% от общите заявки. („връзка към доклада на Gatling“).

LSMDB —Внедряването на LSM успя да се справи с това натоварване и да премине теста. (връзка към доклада на Gatling)

История за този блог

Научаването на концепция на теория и действителното й прилагане са много различни преживявания. Въпреки че има достатъчно статии, документи и блогове в интернет за LSM, няма какво да се намери за подробности за внедряването, така че исках да публикувам поредица от блогове за предизвикателства и предупреждения при писането на база данни ключ-стойност, подкрепена от LSM, но бях скептични за това колко уместно би било това в ерата на големите езикови модели, достъпни за масите чрез ChatGPT и Bard.
Но този експеримент ми дава достатъчно увереност, че писането за моите наклонности все още е уместно (поне засега така или иначе) .

Благодаря ви, че отделихте време да прочетете или дори да прегледате работата ми.