Skip to content

Commit bffcbcf

Browse files
authored
Merge branch 'main' into QoS_Sweep_ver2
2 parents 1ef80ab + a3a20ed commit bffcbcf

10 files changed

Lines changed: 1967 additions & 159 deletions

File tree

README.md

Lines changed: 36 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Our purpose is to provide a "scientific scale" for optimizing distributed system
2020
- [Quick Steps](#quick-steps)
2121
- [Preliminaries](#preliminaries)
2222
- [Directory Structure](#directory-structure)
23-
- [Preparation of Hosts](#preparation-of-hosts)
23+
- [Setup](#setup)
2424
- [Usage in Details](#usage-in-details)
2525
- [Step1: Define Topology](#step1-define-topology)
2626
- [Step2: Generate Execution Scripts](#step2-generate-execution-scripts)
@@ -171,160 +171,13 @@ Before starting multi-host benchmarks, it is helpful to understand an overview o
171171
| `ros2_node_impl_ws/` | ROS 2 node implementation workspace for generated execution scripts. |
172172
| `docker/` | Shared Docker image definition and Compose-related assets. |
173173

174-
### Preparation of Hosts
175-
176-
This section describes the requirements and setup steps for each Host to run this framework.
177-
178-
#### Requirements
179-
180-
Here is the baseline environment we have tested so far.
181-
182-
- Ubuntu 24.04
183-
- Verified devices: Raspberry Pi 4 and Raspberry Pi 5.
184-
- Other devices or servers should also work if Ubuntu 24.04 is available.
185-
- User and repository path assumption:
186-
- Scripts and examples in this repository assume user `ubuntu` and `/home/ubuntu/ros2-perf-multihost`.
187-
- If your username and path differ, how to override these settings is described later.
188-
- The default `ubuntu` user needs passwordless `sudo` only for `chronyc` (described later).
189-
190-
#### SSH access (on the Manager)
191-
192-
This framework assumes that the Manager can SSH into each Host by hostname only, without a password (using key-based authentication).
193-
Therefore, configure the following settings on the Manager machine to meet this requirement.
194-
195-
- Generate and register SSH keys (e.g., `ssh-keygen -t ed25519 && ssh-copy-id ubuntu@host1`).
196-
- Ensure hostnames are resolvable from the Manager.
197-
- Consider assigning static IP addresses to each Host to avoid SSH connectivity issues after a reboot or DHCP lease renewal.
198-
- Recommended Manager-side configuration examples:
199-
- `/etc/hosts`:
200-
```text
201-
<snipped.>
202-
192.168.10.11 host1
203-
192.168.10.12 host2
204-
192.168.10.13 host3
205-
<snipped.>
206-
```
207-
- `~/.ssh/config`:
208-
```text
209-
Host host1
210-
User ubuntu
211-
IdentityFile ~/.ssh/id_ed25519
212-
Host host2
213-
User ubuntu
214-
IdentityFile ~/.ssh/id_ed25519
215-
Host host3
216-
User ubuntu
217-
IdentityFile ~/.ssh/id_ed25519
218-
```
219-
220-
#### Clone this repository
221-
222-
Clone this repository on each Host. We recommend cloning it into the home directory.
174+
## Setup
223175

224-
```bash
225-
cd ~
226-
git clone https://github.com/hal-lab-u-tokyo/ros2-perf-multihost.git
227-
```
228-
229-
#### Docker and the published image
230-
231-
Install Docker Engine and enable non-root usage.
232-
233-
- Follow the official [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) guide.
234-
- To run Docker commands as a non-root user, add your user to the `docker` group:
235-
```bash
236-
sudo usermod -aG docker $USER
237-
```
238-
Then log out and log back in, or run `newgrp docker` to update the group membership.
239-
240-
Pull the published GitHub Packages image [`ghcr.io/hal-lab-u-tokyo/ros2-perf-multihost:latest`](https://github.com/hal-lab-u-tokyo/ros2-perf-multihost/pkgs/container/ros2-perf-multihost).
241-
242-
```bash
243-
docker pull ghcr.io/hal-lab-u-tokyo/ros2-perf-multihost:latest
244-
```
245-
246-
For details on the Docker image, see [docker/README.md](./docker/README.md).
247-
248-
#### [Optional] Native ROS 2 Environment
249-
250-
If you want to evaluate native execution mode as well, install ROS 2 and build the package.
251-
252-
Follow the official [ROS 2 Jazzy Installation steps](https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html).
253-
Other ROS 2 distributions may also work, but they are not officially tested yet.
254-
255-
To benchmark with non-default RMW implementations, install the corresponding packages:
256-
257-
```bash
258-
# For CycloneDDS (rmw_cyclonedds_cpp)
259-
sudo apt install -y ros-jazzy-rmw-cyclonedds-cpp
260-
261-
# For Zenoh (rmw_zenoh_cpp)
262-
sudo apt install -y ros-jazzy-rmw-zenoh-cpp
263-
```
264-
265-
Then, build the ROS 2 package used by this framework in `ros2_node_impl_ws/` (see [ros2_node_impl_ws/README.md](./ros2_node_impl_ws/README.md) for details on ROS 2 node features).
266-
267-
```bash
268-
source /opt/ros/jazzy/setup.bash
269-
cd ros2_node_impl_ws
270-
colcon build --packages-select ros2_perf_multihost_nodes
271-
```
272-
273-
It is recommended to add the following to your `~/.bashrc` so the built package is automatically sourced in every shell session:
274-
275-
```bash
276-
echo "source ~/ros2-perf-multihost/ros2_node_impl_ws/install/local_setup.bash" >> ~/.bashrc
277-
```
278-
279-
#### Python dependencies
280-
281-
Install the following packages on each target Host:
282-
283-
```bash
284-
sudo apt update
285-
sudo apt install -y python3-flask python3-psutil
286-
```
176+
One-time setup steps are maintained in a dedicated document.
177+
For Manager/Host requirements, SSH setup, Docker and ROS 2 preparation, and chrony configuration, see:
287178

288-
Note that the `python3-requests` package is required on the Manager machine.
289-
Therefore, install the following package on the Manager (not on each Host):
179+
- [SETUP.md](./SETUP.md)
290180

291-
```bash
292-
sudo apt update
293-
sudo apt install -y python3-requests
294-
```
295-
296-
#### Clock synchronization for REST benchmark (chrony)
297-
298-
For remote benchmark reproducibility, the REST server uses [chrony](https://chrony-project.org/) to synchronize the clock between Hosts.
299-
300-
Install and enable chrony as follows:
301-
302-
```bash
303-
sudo apt install -y chrony
304-
sudo systemctl enable --now chrony
305-
```
306-
307-
Because the REST server invokes `sudo -n chronyc` (non-interactive), the `ubuntu` user must be allowed to run `chronyc` via `sudo` without a password.
308-
The sudoers entry below grants passwordless `sudo` only for `/usr/bin/chronyc`, so no other commands are affected.
309-
310-
Check the permission, and if needed, configure the sudoers entry on each Host as follows:
311-
312-
```bash
313-
# Check the permission required by rest_server.py (makestep)
314-
sudo -k
315-
sudo -n chronyc -a makestep
316-
317-
# If this command fails because a password is required, configure the sudoers entry as follows.
318-
cat <<'EOF' | sudo tee /etc/sudoers.d/ros2-perf-chrony
319-
ubuntu ALL=(root) NOPASSWD:/usr/bin/chronyc
320-
EOF
321-
sudo chmod 440 /etc/sudoers.d/ros2-perf-chrony
322-
```
323-
324-
If startup sync fails because `sudo` for `chronyc` requires a password, `rest_server.py` exits and prints guidance with the setup URL.
325-
For other startup sync failures (for example, temporary NTP reachability issues), the server continues startup by default and reports the error in logs. To fail fast on any startup sync failure, set `ROS2_PERF_CHRONY_FAIL_FAST_ON_STARTUP=1`.
326-
327-
For details on synchronization behavior and environment variables, see [remote_hosts_scripts/README.md](./remote_hosts_scripts/README.md#clock-synchronization-chrony).
328181

329182
## Usage in Details
330183

@@ -459,6 +312,28 @@ If the server exits at startup with a chrony sudo permission error, check the ch
459312

460313
For details on the specification of REST server and environment variables, see [remote_hosts_scripts/README.md](./remote_hosts_scripts/README.md#rest_serverpy).
461314

315+
#### Evaluate Clock Skew Before Benchmark (Recommended)
316+
317+
When you need stricter one-way latency interpretation, evaluate inter-host clock skew before running trials.
318+
319+
Stricter REST-based check (recommended for REST benchmark runs):
320+
321+
Prerequisite: start `remote_hosts_scripts/rest_server.py` on each target Host first. If REST is not running/reachable, clock probe requests fail (timeout/connection error) and that Host is recorded as `error`.
322+
323+
```bash
324+
python3 manager_scripts/system_perf/check_clock_skew_rest.py --hosts host1,host2,host3 --samples 30 --interval 0.05
325+
python3 manager_scripts/system_perf/check_clock_skew_rest.py --topology topology_example/simple.json --samples 30 --interval 0.05
326+
```
327+
328+
You can specify `--hosts`, `--topology`, or both.
329+
If both are specified and the host lists do not match, the script prints a warning and aborts without evaluation.
330+
331+
`check_clock_skew_rest.py` saves CSV files under `performance_ws/system_perf/clock_skew/<timestamp>/` by default.
332+
For option details and output field definitions, see:
333+
334+
- [manager_scripts/system_perf/README.md#check_clock_skew_restpy](./manager_scripts/system_perf/README.md#check_clock_skew_restpy)
335+
- [remote_hosts_scripts/README.md#rest_serverpy](./remote_hosts_scripts/README.md#rest_serverpy)
336+
462337
##### Alternative method (manual startup on each Host):
463338

464339
If you prefer to control startup host by host (for example, when debugging a specific Host or when centralized SSH fan-out is not available), you can start `rest_server.py` manually on each target Host.
@@ -476,10 +351,9 @@ python3 remote_hosts_scripts/rest_server.py
476351
Then, run the benchmark script on the Manager.
477352
For `docker` and `native` modes, `performance_test.py` automatically distributes the generated host-specific execution files to each Host.
478353
It then prepares the run and executes each trial via the REST APIs, collects logs from each Host, and aggregates the CSV outputs.
479-
If `metadata.txt` contains multiple QoS cases, `performance_test.py`
480-
automatically expands the sweep: for each QoS case, it runs the requested number
481-
of trials with the same topology and passes that case to the generated scripts
482-
and remote Hosts.
354+
355+
It also runs `system_perf` preflight checks (`check_chrony_manager_sync.py` and `check_clock_skew_rest.py`) before trials on every run.
356+
These preflight outputs are saved under `<ws-dir>/<topology>/results/<timestamp>-<rmw>/system_perf/`.
483357

484358
```bash
485359
python3 performance_test/performance_test.py \
@@ -514,6 +388,10 @@ Arguments:
514388
QoS sweep execution does not require an extra command-line option. It is driven
515389
by the topology JSON used during `generate_exec_scripts.py`.
516390

391+
If `metadata.txt` contains multiple QoS cases, `performance_test.py`
392+
automatically expands the sweep: for each QoS case, it runs the requested number
393+
of trials with the same topology and passes that case to the generated scripts
394+
517395
Example:
518396

519397
```bash
@@ -612,6 +490,7 @@ For details on output directory structure and CSV column definitions, see [perfo
612490

613491
For detailed usage in subdomains, see the following documents:
614492

493+
- [SETUP.md](./SETUP.md): One-time Manager/Host setup, SSH, Docker/ROS2, and chrony configuration.
615494
- [topology_example/README.md](./topology_example/README.md): Topology JSON format, including single QoS and QoS sweep array guidance.
616495
- [manager_scripts/README.md](./manager_scripts/README.md): Script usage, generated file details, `metadata.txt` QoS fields, and runtime QoS options.
617496
- [remote_hosts_scripts/README.md](./remote_hosts_scripts/README.md): REST server endpoints, QoS case forwarding, environment variables, and monitor CSV format.
@@ -626,6 +505,7 @@ Common issues and fixes:
626505
- `python3 manager_scripts/generate_exec_scripts.py ...` fails because output exists: rerun with `--force` or remove the existing topology directory under `performance_ws/`.
627506
- `distribute_exec_scripts.sh` fails with SSH/SCP errors: verify hostnames, SSH keys, and that repository paths are identical across Hosts.
628507
- REST benchmark does not start remote execution: ensure REST servers are running on every target Host (for example, run `./manager_scripts/manage_rest_servers.sh start <topology>` from the Manager before calling `performance_test.py`).
508+
- Clock skew should be measured more strictly before latency trials: run `python3 manager_scripts/system_perf/check_clock_skew_rest.py --hosts host1,host2,host3 --samples 30 --interval 0.05` and review `performance_ws/system_perf/clock_skew/<timestamp>/{summary,pairwise}.csv`.
629509
- Docker mode fails on remote Hosts: pull `ghcr.io/hal-lab-u-tokyo/ros2-perf-multihost:latest` and confirm Docker permissions on each Host.
630510
- Native mode cannot find workspace paths: set `ROS2_PERF_WS` to the project root before running `<host_name>_exec_native.sh`.
631511
- Expected CSV outputs are missing: check `<ws-dir>/<topology>/results/latest-<rmw>/raw_logs/trial<N>/` for trial logs and analyzer error output from the CSV-generation step; `coordination_logs/` only covers the REST prepare/start phases.

0 commit comments

Comments
 (0)