Skip to content

Use ReplicatedLoglet by default#3410

Merged
AhmedSoliman merged 1 commit intomainfrom
pavel/wlmvknkrutpq
Jun 18, 2025
Merged

Use ReplicatedLoglet by default#3410
AhmedSoliman merged 1 commit intomainfrom
pavel/wlmvknkrutpq

Conversation

@pcholakov
Copy link
Contributor

@pcholakov pcholakov commented Jun 17, 2025

Automatically migrates logs metadata to replicated loglet in single-node configuration. This will cause Bifrost to extend the chain with new replicated loglet segments. The commit also removes an old logs initialization path which has sinced been replaced by the provisioning task.

Closes #3129


Testing notes

1.4.0-dev: fresh start

✅ Starts with replicated loglet as expected:

% restatectl logs ls
Logs v25
└ Logs Provider: replicated
 ├ Log replication: {node: 1}
 └ Nodeset size: 0
 L-ID  FROM-LSN  KIND        LOGLET-ID  REPLICATION  SEQUENCER  NODESET
 0     1         Replicated  0_0        {node: 1}    N1:2       [N1]
 1     1         Replicated  1_0        {node: 1}    N1:2       [N1]
 2     1         Replicated  2_0        {node: 1}    N1:2       [N1]
 3     1         Replicated  3_0        {node: 1}    N1:2       [N1]
 4     1         Replicated  4_0        {node: 1}    N1:2       [N1]
...

1.3.2 -> 1.4.0-dev: default loglet config automatic migration

% npx @restatedev/[email protected] --node-name n1

% restatectl logs ls
Logs v2
└ Logs Provider: local
 L-ID  FROM-LSN  KIND   LOGLET-ID  REPLICATION  SEQUENCER  NODESET
 0     1         Local  N/A        N/A          N/A        N/A
 1     1         Local  N/A        N/A          N/A        N/A
 2     1         Local  N/A        N/A          N/A        N/A
 3     1         Local  N/A        N/A          N/A        N/A
 4     1         Local  N/A        N/A          N/A        N/A
 ...

Stop and re-start with 1.4.0-dev: % restate-server --node-name n1

2025-06-17T13:51:34.209045Z INFO restate_server
  Starting Restate Server 1.4.0-dev (debug) (9464d0e8 aarch64-apple-darwin 2025-06-17)
    node_name: "n1"
    config_source: [default]
    base_dir: /Users/pavel/restate/restate/restate-data/n1/

...

2025-06-17T13:51:34.502555Z INFO restate_node
  Migrating default loglet configuration to replicated
on rs:worker-0

...

2025-06-17T13:51:40.503517Z INFO restate_bifrost::watchdog
  [Auto Improvement] Bifrost will reconfigure logs to improve placement. logs=[14, 20, 2, 6, 0, 13, 23, 5]
on rs:worker-8
2025-06-17T13:51:41.503715Z INFO restate_bifrost::watchdog
  [Auto Improvement] Bifrost will reconfigure logs to improve placement. logs=[18, 10, 22, 15, 19, 12, 3, 21]
on rs:worker-12
2025-06-17T13:51:42.505307Z INFO restate_bifrost::watchdog
  [Auto Improvement] Bifrost will reconfigure logs to improve placement. logs=[11, 4, 7, 17, 9, 8, 1, 16]
on rs:worker-5

✅ Migrated as expected:

% restatectl logs ls
Logs v8
└ Logs Provider: replicated
 ├ Log replication: {node: 1}
 └ Nodeset size: 1
 L-ID  FROM-LSN  KIND        LOGLET-ID  REPLICATION  SEQUENCER  NODESET
 0     3         Replicated  0_1        {node: 1}    N1:3       [N1]
 1     3         Replicated  1_1        {node: 1}    N1:3       [N1]
 2     3         Replicated  2_1        {node: 1}    N1:3       [N1]
 3     3         Replicated  3_1        {node: 1}    N1:3       [N1]
 4     3         Replicated  4_1        {node: 1}    N1:3       [N1]
 ...

1.3.2 -> 1.4.0-dev: no migration if loglet type is explicitly configured

RESTATE_BIFROST__DEFAULT_PROVIDER="local" restate-server --node-name n1

✅ No migration as expected:

% restatectl logs ls
Logs v2
└ Logs Provider: local
L-ID  FROM-LSN  KIND   LOGLET-ID  REPLICATION  SEQUENCER  NODESET
0     1         Local  N/A        N/A          N/A        N/A
1     1         Local  N/A        N/A          N/A        N/A
2     1         Local  N/A        N/A          N/A        N/A
3     1         Local  N/A        N/A          N/A        N/A
4     1         Local  N/A        N/A          N/A        N/A
...

1.3.2 -> 1.4.0-dev: no migration if log-server role is not enabled

restate-server --node-name n1 --roles=worker,admin,metadata-server

✅ No migration as expected:

% restatectl logs ls
Logs v2
└ Logs Provider: local
L-ID  FROM-LSN  KIND   LOGLET-ID  REPLICATION  SEQUENCER  NODESET
0     1         Local  N/A        N/A          N/A        N/A
1     1         Local  N/A        N/A          N/A        N/A
2     1         Local  N/A        N/A          N/A        N/A
3     1         Local  N/A        N/A          N/A        N/A
4     1         Local  N/A        N/A          N/A        N/A
...

Automatically migrates logs metadata to replicated loglet in single-node configuration. This will
cause Bifrost to extend the chain with new replicated loglet segments. The commit also removes an
old logs initialization path which has sinced been replaced by the provisioning task.
@pcholakov pcholakov requested a review from AhmedSoliman June 17, 2025 14:46

/// Creates empty metadata if none exists for bifrost and publishes it to metadata
/// manager.
pub async fn init_metadata(&self) -> Result<(), Error> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this path can't be reached anymore now that we wait for an initial logs version on startup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

Comment on lines +777 to +780
if !config.has_role(Role::LogServer) {
// This means that roles were explicitly set; we can not migrate to replicated.
return Ok(());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this warrant a log line to nudge the user towards activating it? I suspect it wouldn't get noticed unless very prominent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. What you have now is good.

@github-actions
Copy link

github-actions bot commented Jun 17, 2025

Test Results

  7 files  ±0    7 suites  ±0   5m 15s ⏱️ +20s
 54 tests ±0   53 ✅ ±0  1 💤 ±0  0 ❌ ±0 
223 runs  ±0  220 ✅ ±0  3 💤 ±0  0 ❌ ±0 

Results for commit 418608d. ± Comparison against base commit 6258c4c.

♻️ This comment has been updated with latest results.

@AhmedSoliman
Copy link
Contributor

Unfortunately, as it stands, we can't perform auto migration to replicated loglet without ensuring that the log has been trimmed after creating the new segments. This is to ensure that users can expand this standalone setup to a cluster safely.

Copy link
Contributor

@AhmedSoliman AhmedSoliman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice work. Thank you for doing a neat job switching our defaults and handling automatic migration as well.

🚢

Comment on lines +777 to +780
if !config.has_role(Role::LogServer) {
// This means that roles were explicitly set; we can not migrate to replicated.
return Ok(());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. What you have now is good.


/// Creates empty metadata if none exists for bifrost and publishes it to metadata
/// manager.
pub async fn init_metadata(&self) -> Result<(), Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

Comment on lines +798 to +805
// Why not ProviderConfiguration::from_configuration(config)? Using the default
// replicated loglet provider configuration is a safer alternative as there might be
// untested config changes that would fail later, while this is an appropriate
// successor to the pre-1.4.0 default local loglet config for single nodes. Anything
// more complex should be done as an explicit reconfiguration by the operator.
let logs_configuration = LogsConfiguration {
default_provider: ProviderConfiguration::default(),
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines +816 to +824
match result {
Ok(_) => {}
Err(err) => {
warn!(
"Failed to update the default loglet configuration in metadata: {}",
err
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if let Err(err) = result { ... } is more appropriate if you don't return anything from the Ok() case.

///
/// Default: Local
/// Default: Replicated
pub default_provider: ProviderKind,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bonus points if we can follow up with a PR that skips serialization if it's the default value already. Same for metadata.

@AhmedSoliman AhmedSoliman merged commit 1df856f into main Jun 18, 2025
27 checks passed
@AhmedSoliman AhmedSoliman deleted the pavel/wlmvknkrutpq branch June 18, 2025 11:12
@github-actions github-actions bot locked and limited conversation to collaborators Jun 18, 2025
@pcholakov
Copy link
Contributor Author

Unfortunately, as it stands, we can't perform auto migration to replicated loglet without ensuring that the log has been trimmed after creating the new segments. This is to ensure that users can expand this standalone setup to a cluster safely.

Addressed through documentation for now #3410 while I think about how best to incorporate this into auto-trimming.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Switch defaults for log provider and metadata server to "replicated"

2 participants