Segment is a simple and fast in-memory key-value database written in Rust.
- Simple to use and understand.
- Keys can be separated into multiple dynamic keyspaces.
- Keyspace level configuration.
Segment's goal to is to provide a simpler and more intuitive in-memory key-value solution. It has certain features that other solutions don't. Let's go over them one by one.
Segment has a concept of keyspaces. You can think of keyspaces like tables in a relational database, except that keyspaces don't have any schema. When the segment server starts there are no keyspaces and you can create as many as you like.
Separating keys into keyspaces comes with a benefit, we can now have keyspace level configurations. Evictors are one such configuration. There are two types of evicros in Segment, expiring evictors and max memory evictors.
The expiring evictor is responsible for evicting expired keys which runs for every keyspaces.
The second type of evictor is max memory evictor, which is responsible for evicting keys when the server reaches the max memory specified in segment.conf
.
Currently there are 3 max memory evictors:
- Nop - Stands for no-operation which doesn't evict any keys.
- Random - Evicts keys in a random order.
- LRU - Evicts keys in a LRU fashion.
There are plans to include even more evictors out of the box in future.
Max memory evitors can configured at a keyspace level, which means that you can have a keyspace that does not evict at all while some keyspaces evict. This is powerful becuase now you don't have to spin up a separate server just because you want to have a separate eviction policy.
Segment is multithreaded, which means it uses locks which can be a deal breaker for some use cases. But It works for most use cases and that's what segment is aiming for.
Segment aims to be easy to use and intuitive. One way we are aiming to solve this is by having only one way of doing things. There is only one command to insert data and one way to get it back, this helps reduce the stuff that a developer needs to remember.
One more thing that we are doing is using simple commands, for example let's take a look at the command to insert some data in a keyspace.
SET my_keyspace my_key my_value IF NOT EXISTS EXPIRE AFTER 60000
This commnd tells the segment server to insert the key my_key
with value my_value
into the keyspace my_keyspace
if the key does not exist already and expire the key after 1 minute (60000ms).
The command reads like english and the intent is clear
A similar command in redis would look like this.
SET my_key my_value NX EX 60
If you are not familiar with redis you will not understand what is happeining here. and if you want to have your ttl in milliseconds there is another flag for that and I don't even remember what it is called and that's the point, to reduce the dev effort.
Segment is built using Rust, so you will need rust and it's toolchain installed on your system. To install rust you can follow the steps here.
After installing you can follow the steps below to build and run segment from source.
- Clone this repository.
cd /path/to/cloned/repo
cargo build --release
- The final binary can be found in
./target/release
After building you will find the segment
binary in the ./target/release
directory.
Segment requires segment.conf
file to start. segment.conf
is the config file that contains several server configurations.
If you have the segment.conf
file in the same directory as the segment binary you can just run the binary however, if the config file is in some separate directory you can start the Segment server using the command below
segment --config=/path/to/segment.conf
If the server is started successfully you will see a log similar to this in your terminal.
2022-10-29T07:23:05.308471Z INFO segment::server: server started on port 1698
Used to create a new keyspace. By defualt it doesn't take any arguments except the name of the keyspace, but you can specify the evictor you want to use for the keyspace.
<KEYSPACE>
- Name of the keyspace that you want to create.
EVICTOR
- Indicates the evictor that you want to use for the keyspace. Possible values includeNOP
,RANDOM
andLRU
.
IF NOT EXISTS
- If a keyspace already exists and you try to create it again the server will throw an error, but if you don't want an error you can pass this flag with the create command.
The return type can be a boolean or an error.
CREATE my_keyspace
CREATE my_keyspace EVICTOR LRU
CREATE my_keyspace EVICTOR LRU IF NOT EXISTS
Used to drop a keyspace.
<KEYSPACE>
- Name of the keyspace that you want to drop.
IF EXISTS
- If a keyspace doesn't already exists and you try to drop it the server will throw an error, but if you don't want an error you can pass this flag with the drop command.
The return type can be a boolean or an error.
DROP my_keyspace
DROP my_keyspace IF EXISTS
Used to insert a value in the keyspace.
<KEYSPACE>
- Name of the keyspace that you want to create.<KEY>
- Key that you want to insert.<VALUE>
- Value for the key.
EXPIRE AFTER
- Expiry time of the key in milliseconds after which it will expire.EXPIRE AT
- Unix timestamp after which the key will expire.
IF NOT EXISTS
- If you want to set a key only if it does not already exists.IF EXISTS
- If you want to set a key only if it already exists.
The return type can be a boolean or an error.
SET my_keyspace my_key my_value
SET my_keyspace my_key my_value IF NOT EXISTS
SET my_keyspace my_key my_value IF EXISTS
SET my_keyspace my_key my_value EXPIRE AFTER 60000
SET my_keyspace my_key my_value EXPIRE AT 1667041052
Used to get a key from the keyspace.
<KEYSPACE>
- Name of the keyspace that you want to get the key from.<KEY>
- key that you want to get.
The return type can be a string, null, or error.
GET my_keyspace my_key
Used to delete a key from the keyspace.
<KEYSPACE>
- Name of the keyspace that you want to create.<KEY>
- Name of the keyspace that you want to create.
The return type can be a boolean or error.
DEL my_keyspace my_key
Returns the number of keys in a keyspace.
<KEYSPACE>
- Name of the keyspace.
The return type can be an integer or error.
COUNT my_keyspace
Returns the remaining TTL of the key in milliseconds.
<KEYSPACE>
- Name of the keyspace.<KEY>
- Name of the key.
The return type can be an integer or null (if the key doesn't have an expiry or is already expired) or an error.
TTL my_keyspace my_key
Used to ping the server.
The return type is the string pong
.
PING
Returns the list of keyspaces.
The return type is an array of strings.
KEYSPACES