Un protocol natiu, no pas pgwire

Parlar el protocol de cable de Postgres (pgwire) donaria accés immediat a tot un ecosistema, i es va avaluar seriosament. Va guanyar el natiu perquè allò que fa que valgui la pena connectar-se a Arkeion — enganxar-se a una branca, migrar, diff, merge, verify sobre la connexió — no encaixa amb pgwire sense abusar-ne amb variables de sessió i sintaxi improvisada. Una capa de compatibilitat pgwire per a CRUD pelat continua sent una possible addició futura; el que un servidor Arkeion ven és precisament allò que pgwire no sap dir.

Open-core, amb la línia traçada al repositori

La frontera de l’open-core es traça al nivell del repositori, de manera que la biblioteca oberta es manté pura i el servidor comercial no l’ha de tocar mai.

Arkeion motor incrustat + protocol de cable MIT / Apache-2.0 client SDK / driver de Rust MIT / Apache-2.0 la línia de l'obert arkeiond el dimoni servidor propietari
El motor, el protocol i el client són oberts perquè adoptar-ho no costi; el servidor és on viu el cloud comercial.
  • El motor i el protocol es distribueixen junts i es mantenen oberts. El protocol de cable està escrit a mà — sense serde — i reaprofita la codificació de varints i de valors del mateix motor.
  • El client és un SDK de Rust síncron (use_branch, execute, query, query_as_of, verify). Mantenir-lo obert és el que fa que el servidor sigui adoptable.
  • El servidor, arkeiond, és propietari. Funciona amb un fil per connexió i sense runtime asíncron, cosa que s’adiu amb el motor d’escriptor únic i manté petita la cadena de subministrament. Oferir-lo com a servei gestionat requereix l’aprovació prèvia de Syrakon.

Una sessió és una vista sobre una branca

Una connexió TCP és una sessió, i una sessió és una vista sobre una branca (main per defecte, commutable). L’escriptor únic del motor serialitza les escriptures de tots els clients; les lectures s’executen contra snapshots — inclòs AS OF — en paral·lel, i no es bloquegen mai.

sessió · main sessió · feat-x sessió · main escriptor únic serialitza les escriptures un fitxer les lectures (snapshots, AS OF) van en paral·lel — mai no es bloquegen
Cada sessió veu la seva pròpia branca; les escriptures passen en cua per un únic escriptor i les lectures no esperen mai.

De l’escriptor únic se’n deriven dues conseqüències. El sostre d’escriptura del servidor és el sostre de l’escriptor, així que el group commit — amortitzar el fdatasync de cada commit entre clients — és una optimització planificada. I com que una transacció oberta reté el lock d’escriptura durant tota la seva vida, calen temps d’espera i cancel·lació perquè un client encallat no pugui aturar la resta.

Sobre el cable

L’enquadrament és deliberadament avorrit: una trama amb prefix de longitud que transporta una càrrega útil etiquetada, limitada a 64 MiB perquè una trama defectuosa no pugui esgotar la memòria.

frame   = [u32 LE length][payload]
payload = [u8 tag][fields...]         # fields use the engine's varint + value codec

tag → message
  Hello / Welcome        handshake
  UseBranch              switch the session's branch
  Execute → Affected     a write; returns rows affected
  Query{AS OF} → Rows     a read, optionally against a past version
  Verify → Audit         cryptographic check; returns the chain hash
  Error                  structured failure
longitud u32 LE ≤ 64 MiB càrrega útil etiqueta u8 camps — varint + còdec de valor llegeix la longitud i després exactament aquests bytes
Primer la longitud, després una càrrega útil etiquetada: prou per emmarcar qualsevol missatge sense una biblioteca d'esquemes.

Seguretat

  • El xifratge en trànsit (TLS) complementa el xifratge en repòs del motor. La primera versió parla en text pla a localhost; TLS és al full de ruta immediat.
  • La capa de connexió és on viuen l’autenticació, els rols i els permisos per branca — per exemple, main de només lectura per a alguns clients i una branca de funcionalitat escrivible per a d’altres.

Estat

El protocol, el client i el servidor ja hi són: CRUD, aïllament de branques, AS OF, verify i diff/merge funcionen tots sobre un socket real. El següent de la llista són les transaccions multisentència (amb un temps d’espera per a l’escriptor), després TLS amb autenticació i permisos per branca, i — opcionalment — una capa de compatibilitat pgwire per a CRUD genèric.