Files
SQS-service/tests/compare_sqs.sh
T

273 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# compare_sqs.sh — сравнительный бенчмарк Yandex MQ vs shared-sqs
# Запуск из ЛОКАЛИ для равных условий
# Created: 2026-04-11
set -uo pipefail
# ═══ CREDENTIALS ═══
# Yandex MQ
Y_AK="YCAJEQDz_Eg_i4C4M7TAen2fd"
Y_SK="YCMDfD8OKFK51knPyydwQOYts7Q81_3YBhv4sd_j"
Y_REGION="ru-central1"
Y_ENDPOINT="https://message-queue.api.cloud.yandex.net"
Y_QURL="https://message-queue.api.cloud.yandex.net/b1gatc4m3hv1ldldhljp/dj60000000k2jb2o02mt/foropus"
# Our SQS
O_AK="SSAK-ed0b0c64dcc135adad9e11be"
O_SK="f917c133e4ad74cf37c8e3ba29d74a39f42f117a202bd672436c92fdb6b6f3dc"
O_REGION="us-east-1"
O_ENDPOINT="https://qu.kube5s.ru"
O_QURL="https://qu.kube5s.ru/t-e0ce25e83be94c58/foropus-test"
# ═══ ПАРАМЕТРЫ ═══
SEQ_COUNT=20 # последовательных send/receive
PAR_WORKERS=10 # параллельных воркеров
PAR_MSGS=5 # сообщений на воркер (итого 50)
BURST=30 # burst одновременно
TMPDIR_CMP=$(mktemp -d /tmp/sqs_compare_XXXXX)
trap "rm -rf $TMPDIR_CMP" EXIT
# ═══ ХЕЛПЕРЫ ═══
ysqs() {
AWS_ACCESS_KEY_ID="$Y_AK" AWS_SECRET_ACCESS_KEY="$Y_SK" \
AWS_DEFAULT_REGION="$Y_REGION" \
aws --endpoint-url "$Y_ENDPOINT" --output json sqs "$@" 2>&1
}
osqs() {
AWS_ACCESS_KEY_ID="$O_AK" AWS_SECRET_ACCESS_KEY="$O_SK" \
AWS_DEFAULT_REGION="$O_REGION" \
aws --endpoint-url "$O_ENDPOINT" --output json sqs "$@" 2>&1
}
# ms_since — миллисекунды с момента $1
ms_now() { date +%s%3N; }
echo "╔═══════════════════════════════════════════════════════════════════╗"
echo "║ BENCHMARK: Yandex MQ vs shared-sqs — $(date '+%Y-%m-%d %H:%M:%S') ║"
echo "║ Из локали, равные условия ║"
echo "╚═══════════════════════════════════════════════════════════════════╝"
echo ""
# ═══════════════════════════════════════
# 1. SEQUENTIAL SEND — latency per message
# ═══════════════════════════════════════
echo "═══ 1. Sequential SendMessage (${SEQ_COUNT} msgs) ═══"
# Yandex
echo -n " Yandex: "
Y_START=$(ms_now)
Y_SEND_OK=0
for i in $(seq 1 $SEQ_COUNT); do
R=$(ysqs send-message --queue-url "$Y_QURL" --message-body "bench-seq-${i}")
if echo "$R" | grep -q "MessageId"; then Y_SEND_OK=$((Y_SEND_OK+1)); fi
echo -n "."
done
Y_SEND_MS=$(( $(ms_now) - Y_START ))
Y_SEND_AVG=$(( Y_SEND_MS / SEQ_COUNT ))
echo " ${Y_SEND_OK}/${SEQ_COUNT} ok, ${Y_SEND_MS}ms total, avg=${Y_SEND_AVG}ms"
# Ours
echo -n " Ours: "
O_START=$(ms_now)
O_SEND_OK=0
for i in $(seq 1 $SEQ_COUNT); do
R=$(osqs send-message --queue-url "$O_QURL" --message-body "bench-seq-${i}")
if echo "$R" | grep -q "MessageId"; then O_SEND_OK=$((O_SEND_OK+1)); fi
echo -n "."
done
O_SEND_MS=$(( $(ms_now) - O_START ))
O_SEND_AVG=$(( O_SEND_MS / SEQ_COUNT ))
echo " ${O_SEND_OK}/${SEQ_COUNT} ok, ${O_SEND_MS}ms total, avg=${O_SEND_AVG}ms"
echo ""
# ═══════════════════════════════════════
# 2. SEQUENTIAL RECEIVE — latency per message
# ═══════════════════════════════════════
echo "═══ 2. Sequential ReceiveMessage (${SEQ_COUNT} msgs) ═══"
# Yandex
echo -n " Yandex: "
Y_START=$(ms_now)
Y_RECV_OK=0
for i in $(seq 1 $SEQ_COUNT); do
R=$(ysqs receive-message --queue-url "$Y_QURL" --max-number-of-messages 1 --wait-time-seconds 2)
if echo "$R" | grep -q "MessageId"; then
Y_RECV_OK=$((Y_RECV_OK+1))
H=$(echo "$R" | grep -oP '"ReceiptHandle"\s*:\s*"\K[^"]+')
ysqs delete-message --queue-url "$Y_QURL" --receipt-handle "$H" >/dev/null 2>&1
fi
echo -n "."
done
Y_RECV_MS=$(( $(ms_now) - Y_START ))
Y_RECV_AVG=$(( Y_RECV_MS / SEQ_COUNT ))
echo " ${Y_RECV_OK}/${SEQ_COUNT} ok, ${Y_RECV_MS}ms total, avg=${Y_RECV_AVG}ms"
# Ours
echo -n " Ours: "
O_START=$(ms_now)
O_RECV_OK=0
for i in $(seq 1 $SEQ_COUNT); do
R=$(osqs receive-message --queue-url "$O_QURL" --max-number-of-messages 1 --wait-time-seconds 2)
if echo "$R" | grep -q "MessageId"; then
O_RECV_OK=$((O_RECV_OK+1))
H=$(echo "$R" | grep -oP '"ReceiptHandle"\s*:\s*"\K[^"]+')
osqs delete-message --queue-url "$O_QURL" --receipt-handle "$H" >/dev/null 2>&1
fi
echo -n "."
done
O_RECV_MS=$(( $(ms_now) - O_START ))
O_RECV_AVG=$(( O_RECV_MS / SEQ_COUNT ))
echo " ${O_RECV_OK}/${SEQ_COUNT} ok, ${O_RECV_MS}ms total, avg=${O_RECV_AVG}ms"
echo ""
# ═══════════════════════════════════════
# 3. PARALLEL SEND — throughput
# ═══════════════════════════════════════
TOTAL_PAR=$((PAR_WORKERS * PAR_MSGS))
echo "═══ 3. Parallel SendMessage (${PAR_WORKERS} workers × ${PAR_MSGS} = ${TOTAL_PAR} msgs) ═══"
# Yandex
echo -n " Yandex: "
Y_START=$(ms_now)
for w in $(seq 1 $PAR_WORKERS); do
(
ok=0
for m in $(seq 1 $PAR_MSGS); do
R=$(ysqs send-message --queue-url "$Y_QURL" --message-body "par-${w}-${m}")
if echo "$R" | grep -q "MessageId"; then ok=$((ok+1)); fi
done
echo "$ok" > "${TMPDIR_CMP}/y_par_${w}"
) &
done
wait
Y_PAR_MS=$(( $(ms_now) - Y_START ))
Y_PAR_OK=0
for w in $(seq 1 $PAR_WORKERS); do
[[ -f "${TMPDIR_CMP}/y_par_${w}" ]] && Y_PAR_OK=$((Y_PAR_OK + $(cat "${TMPDIR_CMP}/y_par_${w}")))
done
Y_PAR_RPS=$(( Y_PAR_OK * 1000 / Y_PAR_MS ))
echo "${Y_PAR_OK}/${TOTAL_PAR} ok, ${Y_PAR_MS}ms, ~${Y_PAR_RPS} msg/sec"
# Ours
echo -n " Ours: "
O_START=$(ms_now)
for w in $(seq 1 $PAR_WORKERS); do
(
ok=0
for m in $(seq 1 $PAR_MSGS); do
R=$(osqs send-message --queue-url "$O_QURL" --message-body "par-${w}-${m}")
if echo "$R" | grep -q "MessageId"; then ok=$((ok+1)); fi
done
echo "$ok" > "${TMPDIR_CMP}/o_par_${w}"
) &
done
wait
O_PAR_MS=$(( $(ms_now) - O_START ))
O_PAR_OK=0
for w in $(seq 1 $PAR_WORKERS); do
[[ -f "${TMPDIR_CMP}/o_par_${w}" ]] && O_PAR_OK=$((O_PAR_OK + $(cat "${TMPDIR_CMP}/o_par_${w}")))
done
O_PAR_RPS=$(( O_PAR_OK * 1000 / O_PAR_MS ))
echo "${O_PAR_OK}/${TOTAL_PAR} ok, ${O_PAR_MS}ms, ~${O_PAR_RPS} msg/sec"
echo ""
# ═══════════════════════════════════════
# 4. BURST — все сразу
# ═══════════════════════════════════════
echo "═══ 4. Burst SendMessage (${BURST} одновременно) ═══"
# Yandex
echo -n " Yandex: "
Y_START=$(ms_now)
for b in $(seq 1 $BURST); do
( R=$(ysqs send-message --queue-url "$Y_QURL" --message-body "burst-${b}")
echo "$R" | grep -q "MessageId" && echo 1 || echo 0
) > "${TMPDIR_CMP}/y_burst_${b}" &
done
wait
Y_BURST_MS=$(( $(ms_now) - Y_START ))
Y_BURST_OK=0
for b in $(seq 1 $BURST); do
[[ -f "${TMPDIR_CMP}/y_burst_${b}" ]] && Y_BURST_OK=$((Y_BURST_OK + $(cat "${TMPDIR_CMP}/y_burst_${b}")))
done
echo "${Y_BURST_OK}/${BURST} ok, ${Y_BURST_MS}ms"
# Ours
echo -n " Ours: "
O_START=$(ms_now)
for b in $(seq 1 $BURST); do
( R=$(osqs send-message --queue-url "$O_QURL" --message-body "burst-${b}")
echo "$R" | grep -q "MessageId" && echo 1 || echo 0
) > "${TMPDIR_CMP}/o_burst_${b}" &
done
wait
O_BURST_MS=$(( $(ms_now) - O_START ))
O_BURST_OK=0
for b in $(seq 1 $BURST); do
[[ -f "${TMPDIR_CMP}/o_burst_${b}" ]] && O_BURST_OK=$((O_BURST_OK + $(cat "${TMPDIR_CMP}/o_burst_${b}")))
done
echo "${O_BURST_OK}/${BURST} ok, ${O_BURST_MS}ms"
echo ""
# ═══════════════════════════════════════
# 5. GetQueueAttributes — latency
# ═══════════════════════════════════════
echo "═══ 5. GetQueueAttributes (5 раз) ═══"
echo -n " Yandex: "
Y_START=$(ms_now)
for i in $(seq 1 5); do
ysqs get-queue-attributes --queue-url "$Y_QURL" --attribute-names ApproximateNumberOfMessages >/dev/null 2>&1
echo -n "."
done
Y_ATTR_MS=$(( $(ms_now) - Y_START ))
Y_ATTR_AVG=$(( Y_ATTR_MS / 5 ))
echo " ${Y_ATTR_MS}ms total, avg=${Y_ATTR_AVG}ms"
echo -n " Ours: "
O_START=$(ms_now)
for i in $(seq 1 5); do
osqs get-queue-attributes --queue-url "$O_QURL" --attribute-names ApproximateNumberOfMessages >/dev/null 2>&1
echo -n "."
done
O_ATTR_MS=$(( $(ms_now) - O_START ))
O_ATTR_AVG=$(( O_ATTR_MS / 5 ))
echo " ${O_ATTR_MS}ms total, avg=${O_ATTR_AVG}ms"
echo ""
# ═══════════════════════════════════════
# 6. PURGE — очистка после тестов
# ═══════════════════════════════════════
echo "═══ 6. Purge (очистка) ═══"
ysqs purge-queue --queue-url "$Y_QURL" >/dev/null 2>&1 && echo " Yandex: purged" || echo " Yandex: purge failed (cooldown?)"
osqs purge-queue --queue-url "$O_QURL" >/dev/null 2>&1 && echo " Ours: purged" || echo " Ours: purge failed"
echo ""
# ═══════════════════════════════════════
# ИТОГОВАЯ ТАБЛИЦА
# ═══════════════════════════════════════
echo "╔══════════════════════════════════════════════════════════════════════════╗"
echo "║ РЕЗУЛЬТАТЫ СРАВНЕНИЯ ║"
echo "╠══════════════════════════╦══════════════════╦══════════════════╦════════╣"
echo "║ Тест ║ Yandex MQ ║ shared-sqs ║ Winner ║"
echo "╠══════════════════════════╬══════════════════╬══════════════════╬════════╣"
printf "║ %-24s ║ %4dms avg %2d/%2d ║ %4dms avg %2d/%2d ║ %-6s ║\n" \
"Seq Send (${SEQ_COUNT}msg)" "$Y_SEND_AVG" "$Y_SEND_OK" "$SEQ_COUNT" "$O_SEND_AVG" "$O_SEND_OK" "$SEQ_COUNT" \
"$([ $Y_SEND_AVG -le $O_SEND_AVG ] && echo 'YMQ' || echo 'OURS')"
printf "║ %-24s ║ %4dms avg %2d/%2d ║ %4dms avg %2d/%2d ║ %-6s ║\n" \
"Seq Recv+Del (${SEQ_COUNT}msg)" "$Y_RECV_AVG" "$Y_RECV_OK" "$SEQ_COUNT" "$O_RECV_AVG" "$O_RECV_OK" "$SEQ_COUNT" \
"$([ $Y_RECV_AVG -le $O_RECV_AVG ] && echo 'YMQ' || echo 'OURS')"
printf "║ %-24s ║ %4dms %3d msg/s ║ %4dms %3d msg/s ║ %-6s ║\n" \
"Parallel Send (${TOTAL_PAR}msg)" "$Y_PAR_MS" "$Y_PAR_RPS" "$O_PAR_MS" "$O_PAR_RPS" \
"$([ $Y_PAR_RPS -ge $O_PAR_RPS ] && echo 'YMQ' || echo 'OURS')"
printf "║ %-24s ║ %4dms %2d/%2d ║ %4dms %2d/%2d ║ %-6s ║\n" \
"Burst (${BURST} simultaneous)" "$Y_BURST_MS" "$Y_BURST_OK" "$BURST" "$O_BURST_MS" "$O_BURST_OK" "$BURST" \
"$([ $Y_BURST_MS -le $O_BURST_MS ] && echo 'YMQ' || echo 'OURS')"
printf "║ %-24s ║ %4dms avg ║ %4dms avg ║ %-6s ║\n" \
"GetQueueAttributes (5x)" "$Y_ATTR_AVG" "$O_ATTR_AVG" \
"$([ $Y_ATTR_AVG -le $O_ATTR_AVG ] && echo 'YMQ' || echo 'OURS')"
echo "╚══════════════════════════╩══════════════════╩══════════════════╩════════╝"