Skip to content

Why not Apache Fluss

Fun fact

Fluss's mascot is an otter. A mink is the otter's smaller, more slender cousin in the same family, Mustelidae: partially webbed feet instead of fully webbed, solitary instead of living in groups, and stealthy rather than playful. The analogy: Mink carries no Flink, RocksDB or ZooKeeper dependency, keeps no durable local state and the node is one binary.

Apache Fluss is the project Mink is modelled on. The table model is: log tables and primary-key tables, buckets and partitions, a changelog per primary-key table, merge engines, lakehouse tiering with a union read over lake plus log. The difference is where the bytes live and how the cluster agrees on anything.

Storage

Fluss tablet servers keep the log and the KV state on local disks and replicate each bucket to an in-sync replica set. Mink nodes hold no durable local state. Both the log and KV snapshots go to object storage. A node that dies is replaced by another node opening the same stream.

MinkFluss
Log durabilityWAL on object storage through s3stream, one copy in the object storeLocal disks, ISR replication across tablet servers, acks
Log segmentsStream objects in the object storeLocal segments, tiered to remote log storage after a delay
KV stateLocal working copy rebuilt from a KV snapshot in the object store plus log replayRocksDB on local disk, snapshots to remote storage
Cross-AZ trafficObject store onlyReplication between servers
Append latencyObject-store write latency, tens of millisecondsLocal disk plus replication, milliseconds

Coordination

MinkFluss
MetadataOrdered command log in Postgres or SQLite, tailed by every nodeCoordinatorServer with ZooKeeper
Bucket leadershipCoordinator on the lease holder assigns. Stream epochs fence the old ownerCoordinator elects among replicas. Leader epoch fences
FailoverAny live node opens the stream with a higher epochAnother in-sync replica becomes leader
MembershipHeartbeat rows in the metadata databaseZooKeeper sessions

Tables

MinkFluss
Table typesLog, primary-keyLog, primary-key
Merge enginesDefault (last write), first_row, versioned, aggregationDefault, first_row, versioned, aggregation
Partial updateYesYes
Changelog imagefull or walfull or wal
Auto incrementYes, one columnYes, one column
Schema evolutionAdd, drop, rename, modify with type promotionAdd, drop, rename, modify
Row formatArrow IPC batches on the log, compacted rows in KVArrow or indexed rows on the log, compacted or indexed rows in KV
BucketingNative, Paimon and Iceberg hash functionsNative, Paimon and Iceberg hash functions
Default log TTL7 days7 days

Protocols

MinkFluss
Native APIArrow Flight over gRPCCustom RPC over Netty
KafkaProducers, consumers, consumer groups, idempotent producers. No transactionsKafka protocol plugin
SQLFlight SQL from mink-query on DataFusionFlink SQL, Spark
Flink connectorNot yetSource, sink, lookup join, delta join
ImplementationRust, one static binary per roleJava, targets Java 11, runs on a JVM
Client languagesRustJava
AuthenticationNot implementedSASL/PLAIN, ACLs

Lakehouse

MinkFluss
FormatsIcebergPaimon, Iceberg, Lance
TieringWorker on the coordinator leader, per-table freshnessFlink tiering service
Lake table schemaThe user's schemaThe user's schema since 1.0, __bucket, __offset, __timestamp on tables from earlier versions
Attach existing tableYes, with schema and partition checksNo
Lake compactionTiering worker rewrites small files, opt in per tableTiering service, opt in per table
Union readServer-side, Arrow Flight and Flight SQLFlink connector
Offset bookkeepingmink-offsets snapshot property, per bucketSnapshot property, per bucket

Coming soon

Mink tiering to Paimon, Lance and DuckLake.

Choosing

Both projects store tables, tier history into a lakehouse format and let lakehouse engines read the tiered files directly. They differ in where the work is done and what a client has to know.

MinkFluss
Union readOn the server. A client asks for the table and gets lake plus log as one streamIn the Flink connector. The client loads the Paimon or Iceberg plugin and merges lake and log itself
What a client knowsTable, bucket, offsetTable, bucket, offset, the lake format and its catalog
Client pathKafka, Arrow Flight, Flight SQLFlink connector, Java client, Kafka protocol plugin
Compute couplingNone. Any engine over Flight SQL or IcebergFlink for tiering, joins and the primary connector. Spark and StarRocks in progress
Processesmink nodesCoordinatorServer, TabletServers, ZooKeeper, a Flink cluster for tiering and connectors
Durable state on nodesNone. Log and snapshots are objectsLog and RocksDB on local disk, replicated across TabletServers
CoordinationSQL databaseZooKeeper
RuntimeRust binaryJava 11 JVM

Coming soon

Mink connectors for Flink, Spark, Trino and DuckDB.