You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+37-12Lines changed: 37 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ For scalability details, see [benchmarks](/benchmarks/README.md).
12
12
13
13
## How it works
14
14
15
-
We just need to have three tables (postgres syntax):
15
+
We just need to have a few tables (postgres syntax):
16
16
17
17
```sql
18
18
CREATETABLEtopic (
@@ -21,26 +21,51 @@ CREATE TABLE topic (
21
21
created_at TIMESTAMPNOT NULL DEFAULT NOW()
22
22
);
23
23
24
+
CREATETABLEconsumer (
25
+
topic TEXTNOT NULL,
26
+
name TEXTNOT NULL,
27
+
partition SMALLINTNOT NULL,
28
+
first_event_id BIGINT,
29
+
last_event_id BIGINT,
30
+
last_consumption_at TIMESTAMP,
31
+
consumed_events BIGINTNOT NULL,
32
+
created_at TIMESTAMPNOT NULL DEFAULT NOW(),
33
+
PRIMARY KEY (topic, name, partition)
34
+
);
35
+
24
36
CREATETABLEevent (
25
37
topic TEXTNOT NULL,
26
38
id BIGSERIALNOT NULL,
27
39
partition SMALLINTNOT NULL,
28
40
key TEXT,
29
41
value BYTEANOT NULL,
42
+
buffered_at TIMESTAMPNOT NULL,
30
43
created_at TIMESTAMPNOT NULL DEFAULT NOW(),
31
44
metadata JSON NOT NULL,
32
45
PRIMARY KEY (topic, id)
33
46
) PARTITION BY LIST (topic);
34
47
35
-
CREATETABLEconsumer (
48
+
-- Same schema as event, just not partitioned. --
49
+
-- It is used to handle eventual consistency of auto increment; --
50
+
-- there is no guarantee that record of id 2 is visible after id 1 record. --
51
+
-- Events are first inserted to the event_buffer; --
52
+
-- they are then moved to event table in bulk, by a single, serialized writer; --
53
+
-- because there is only one writer, it fixes eventual consistency issue --
54
+
CREATETABLEevent_buffer (
36
55
topic TEXTNOT NULL,
37
-
name TEXTNOT NULL,
56
+
id BIGSERIALPRIMARY KEY,
38
57
partition SMALLINTNOT NULL,
39
-
last_event_id BIGINT,
40
-
last_consumption_at TIMESTAMP,
58
+
key TEXT,
59
+
value BYTEANOT NULL,
41
60
created_at TIMESTAMPNOT NULL DEFAULT NOW(),
42
-
PRIMARY KEY (topic, name, partition)
61
+
metadata JSON NOT NULL
62
+
);
63
+
-- Used to lock single event_buffer to event writer; --
64
+
-- there cannot be more than one record of this table! --
65
+
CREATETABLEevent_buffer_lock (
66
+
created_at TIMESTAMPNOT NULL DEFAULT NOW()
43
67
);
68
+
INSERT INTO event_buffer_lock VALUES (DEFAULT);
44
69
```
45
70
46
71
To consume messages, we just need to periodically (every one to a few seconds) do:
@@ -69,7 +94,7 @@ COMMIT;
69
94
Optionally, to increase throughput & concurrency, we might have a partitioned topic and consumers (-1 partition standing
70
95
for not partitioned topic/consumer/event).
71
96
72
-
Distribution of partitioned events is the sole responsibility of the publisher.
97
+
Distribution of partitioned events is the sole responsibility of a publisher.
73
98
74
99
Consumption of such events per partition (0 in an example) might look like this:
75
100
@@ -105,14 +130,14 @@ them:
105
130
```java
106
131
107
132
importcom.binaryigor.eventsql.EventSQL;
108
-
importjavax.sql.DataSource;
109
133
// dialect of your events backend - POSTGRES, MYSQL, MARIADB and so on;
110
134
// as of now, only POSTGRES has fully tested support;
111
135
// should also work with others but some things - event table partition management for example - works only with Postgres, for others it must be managed manually
112
-
importorg.jooq.SQLDialect;
136
+
importcom.binaryigor.eventsql.EventSQLDialect;
137
+
importjavax.sql.DataSource;
113
138
114
-
var eventSQL =newEventSQL(dataSource, SQLDialect.POSTGRES);
115
-
ver shardedEventSQL =newEventSQL(dataSources, SQLDialect.POSTGRES);
139
+
var eventSQL =newEventSQL(dataSource, EventSQLDialect.POSTGRES);
140
+
ver shardedEventSQL =newEventSQL(dataSources, EventSQLDialect.POSTGRES);
116
141
```
117
142
118
143
Sharded version works in the same vain - it just assumes that topics and consumers are hosted on multiple dbs.
@@ -223,7 +248,7 @@ var consumers = eventSQL.consumers();
0 commit comments