Saturday, September 28, 2024

Script điều chỉnh weight cho các OSDs khi thêm storage node mới

-

Mục đích.

Giám sát và điều chỉnh weight của các thiết bị lưu trữ đối tượng (OSD) cụ thể trong cụm Ceph.

Mục tiêu là đạt được sự phân phối dữ liệu cân bằng trên tất cả các OSD.

Script reweight.sh này được viết để tự động điều chỉnh trọng số của các OSD (Object Storage Daemon) trong một cụm Ceph, dựa trên các điều kiện nhất định.

Chức năng chính.

  • Giám sát trọng lượng OSD: Script kiểm tra định kỳ weight hiện tại của mỗi OSD được liệt kê.
  • Điều chỉnh trọng lượng OSD: Nếu weight của OSD thấp hơn giá trị mục tiêu (được xác định bởi TARGET_WEIGHT), script sẽ tăng weight của nó lên một mức tăng nhỏ (INCREMENT_WEIGHT).
  • Nhận thức về việc lấp đầy dữ liệu: Script chỉ cố gắng điều chỉnh weight của OSD nếu hoạt động lấp đầy dữ liệu của cụm thấp (cho thấy việc di chuyển dữ liệu tối thiểu). Điều này giúp tránh làm gián đoạn các hoạt động di chuyển dữ liệu đang diễn ra.
  • Xác thực: Script bao gồm xác thực cơ bản để đảm bảo các tham số do người dùng xác định là các số hợp lệ trong phạm vi quy định.

Tính năng bổ sung.

Thông báo Telegram: Script có thông báo đến trò chuyện Telegram khi weightcủa OSD được điều chỉnh.

#!/bin/bash
OSDs="1 2 3 4 5 6 7 8 9"
INCREMENT_WEIGHT=0.01 # IMPORTANT
TARGET_WEIGHT=1.45
INTERVAL_CHECK=1 # second
WORK_DIR=/opt/weight

### telegram var
#read -p "Enter TOKEN_BOT: " TELEGRAM_BOT_TOKEN
#TELEGRAM_BOT_TOKEN=$(echo "$TELEGRAM_BOT_TOKEN" | tr -d '"')
#read -p "Enter CHAT_ID: " TELEGRAM_CHAT_ID
TELEGRAM_BOT_TOKEN=''
TELEGRAM_CHAT_ID=''

# basic validation on weird number
validate_weight () {
  local w=$1
  re='^[+-]?[0-9]+\.?[0-9]*$'
  if ! [[ $w =~ $re && $INCREMENT_WEIGHT =~ $re && $TARGET_WEIGHT =~ $re && $INTERVAL_CHECK =~ $re ]] ; then
    echo "xx Not a number" >&2
    exit 1
  elif (( $(echo "$w > $TARGET_WEIGHT" | bc -l) )); then
    echo "xx Weight cannot higher than target"
    exit 1
  elif (( $(echo "$TARGET_WEIGHT > 1.5" | bc -l) )) || (( $(echo "$TARGET_WEIGHT < 0" | bc -l) )); then
    echo "xx TARGET_WEIGHT cannot be out of range [0;1.5]"
    exit 1
  elif (( $(echo "$INCREMENT_WEIGHT > 0.05" | bc -l) )) || (( $(echo "$INCREMENT_WEIGHT < 0" | bc -l) )); then
    echo "xx INCREMENT_WEIGHT cannot be higher than 0.05"
    exit 1
  elif (( $(echo "$INCREMENT_WEIGHT > $TARGET_WEIGHT" | bc -l) )); then
    echo "xx INCREMENT_WEIGHT cannot be higher than TARGET_WEIGHT"
    exit 1
  fi
  return 0
}

## init the weight for listed OSD
## store to /opt/weight.X
for OSD in $OSDs; do
  init_weight=$(printf '%.2f\n' $(ceph  osd df | grep "^$OSD" | awk '{ print $3}'))
  echo $init_weight > $WORK_DIR/weight.$OSD
  echo "=Init $OSD with weight $init_weight"
  validate_weight $init_weight
done

## idea: while loop for keep running
## for loop to loop through OSDs
## 	while loop to wait and reweight
## 	if backfill < 10 and weight < target then reweight

while true; do
  sleep 1 &&
  #if (( $(cat test.ceph-s | grep -E "active\+remapped\+backfilling|active\+remapped\+backfill_wait" | awk '{sum+=$1} END {print sum}') < 15)) 2>/dev/null; then
  if (( $(ceph  -s | grep -E "active\+remapped\+backfilling|active\+remapped\+backfill_wait" | awk '{sum+=$1} END {print sum}') < 15)) 2>/dev/null; then
    #TELERAM_MESSAGE=""
    for OSD in $OSDs; do  # 141 142
      echo "Waiting for osd.$OSD"
      while true; do
        #if (( $(cat test.ceph-s | grep -E "active\+remapped\+backfilling|active\+remapped\+backfill_wait" | awk '{sum+=$1} END {print sum}') < 15 )) 2>/dev/null; then
        if (( $(ceph  -s | grep -E "active\+remapped\+backfilling|active\+remapped\+backfill_wait" | awk '{sum+=$1} END {print sum}') < 15 )) 2>/dev/null; then
          echo "+++++ Start: $(date)"
          ceph  -s | grep backfill
          ## get current weight
          #w=$(cat $WORK_DIR/weight.$OSD)
          w=$(printf '%.2f\n' $(ceph  osd df | grep "^$OSD" | awk '{ print $3}'))

          ## only reweight if current < TARGET_WEIGHT
          if (( $(echo "$w < $TARGET_WEIGHT" | bc -l) )); then

            echo "++ osd.$OSD current weight: $w will increase by $INCREMENT_WEIGHT"

            ## increase the current weight
            w=$(echo $w + $INCREMENT_WEIGHT | bc)
            if (( $(echo "$w < 1" | bc -l) )); then w=0$w; fi  # .21 -> 0.21

            echo "++ reweight: $(date)"
            ## reweight
            #if echo osd.$OSD $w; then
            if ceph osd crush reweight osd.$OSD $w; then
              #echo $w > $WORK_DIR/weight.$OSD;
              #notify
              TELERAM_MESSAGE="== New osd.$OSD weight $w\n$TELERAM_MESSAGE"
              break # out while loop
            fi
          else  # if current >= TARGET_WEIGHT
            break # out while loop
          fi # target-weight check
        fi # backill check
        sleep $INTERVAL_CHECK
      done # inner while-loop
    done # for-loop
    echo "++ Notify Telegram!"
    #curl -X POST --silent --proxy http://192.168.100.100:3128 \
    #  -H "Content-Type: application/json" \
    #  -d "{\"chat_id\":\"$TELEGRAM_CHAT_ID\", \"text\": \"$TELERAM_MESSAGE\", 'disable_notification': true}" \
    #  https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage > /dev/null
  else
    ### one endless loop case is when pgbackfill cleaned so fast and at least one OSD is not get TARGET
    is_break=1
    ceph osd df > /tmp/osd-df # reduce load ceph api
    for OSD in $OSDs; do
      w=$(printf '%.2f\n' $(grep "^$OSD" /tmp/osd-df | awk '{ print $3}'))
      # if all OSD >= TARGET -> BREAK OUTER WHILE
      # if one OSD < TARGET -> BREAK FOR -> CONTINUE TO INCREASE
      if (( $(echo "$w < $TARGET_WEIGHT" | bc -l) )); then
        is_break=0
        break
      else
        OSDs=$(echo $OSDs | sed s/$OSD//)
        echo "++ osd is removed: $OSD. Current list: $OSDs"
      fi
    done

    ## value didn't changed thru for, no OSD < TARGET, then exit while
    if (( $is_break == 1 )); then break 2; fi
  fi
done

Luồng thực thi script.

  • Khởi tạo:
    • Đọc danh sách ID OSD từ biến OSDs.
    • Xác định mức tăng INCREMENT_WEIGHT, TARGET_WEIGHT) và khoảng thời gian kiểm tra INTERVAL_CHECK.
    • Xác thực các tham số do người dùng xác định.
    • Lấy weight ban đầu cho mỗi OSD và lưu trữ nó trong một tệp.
  • Vòng lặp chính:
    • Liên tục lặp lại cho đến khi bị hủy.
    • Kiểm tra tổng hoạt động lấp đầy dữ liệu bằng cách sử dụng ceph -s.
    • Lặp qua từng OSD được liệt kê:
      • Chờ trong vòng lặp cho đến khi hoạt động lấp đầy dữ liệu thấp.
      • Lấy weight hiện tại cho OSD.
      • Nếu weight hiện tại thấp hơn trọng lượng mục tiêu:
        • Tăng weight lên mức tăng đã xác định.
        • Điều chỉnh weight của OSD bằng cách sử dụng ceph osd crush reweight.
        • (Đã được bình luận) Gửi thông báo qua Telegram (nếu được bật).
    • Xử lý tình huống ngoại lệ:
      • Nếu hoạt động lấp đầy dữ liệu vẫn cao đối với tất cả các OSD, script sẽ kiểm tra lại tất cả weight OSD (giảm tải bằng cách lưu đầu ra vào tệp tạm thời).
      • Nếu tất cả các OSD đạt đến weight mục tiêu, script sẽ thoát.
      • Nếu bất kỳ OSD nào vẫn thấp hơn weight mục tiêu, OSD khớp sẽ bị xóa khỏi danh sách và script sẽ tiếp tục lặp qua các OSD còn lại.

Bạn có thể sử dụng kết hợp lại, nohup ./reweight.sh & sẽ chạy script reweight.sh trong nền.

nohup ./reweight.sh &

nohup: Viết tắt của “no hang up”. Đây là một lệnh được sử dụng để chạy một lệnh khác “trong nền” và giữ cho lệnh đó tiếp tục chạy ngay cả khi người dùng đăng xuất khỏi hệ thống. nohup ngăn chặn lệnh được chạy từ việc bị tín hiệu SIGHUP (hang up) gửi đến, điều này thường xảy ra khi terminal đóng lại. Điều này đảm bảo rằng quá trình không bị gián đoạn bởi việc đóng terminal hoặc đăng xuất.

./reweight.sh: Chỉ định rằng script reweight.sh nằm trong thư mục hiện tại sẽ được thực thi. Dấu ./ trước tên file chỉ rõ rằng file đó nằm trong thư mục hiện tại.

&: Khi được đặt ở cuối một lệnh, dấu & cho biết lệnh đó sẽ được thực thi “trong nền” (background). Điều này có nghĩa là bạn không cần phải chờ đợi lệnh hoàn thành và có thể tiếp tục sử dụng terminal cho các lệnh khác ngay lập tức.

Kết hợp lại, nohup ./reweight.sh & sẽ chạy script reweight.sh trong nền, đảm bảo rằng nó tiếp tục chạy ngay cả khi người dùng đăng xuất hoặc terminal được đóng lại, và không chiếm giữ terminal hiện tại, cho phép người dùng thực hiện các lệnh khác ngay sau đó. Đầu ra mặc định của lệnh được chạy bởi nohup sẽ được chuyển hướng vào file nohup.out trong thư mục hiện tại, trừ khi được chỉ định khác.

Kết luận.

Nhìn chung, script này tự động hóa quy trình điều chỉnh weight OSD trong cụm Ceph để đạt được sự phân phối dữ liệu cân bằng hơn đồng thời giảm thiểu sự gián đoạn trong các hoạt động cân bằng lại dữ liệu.

Lưu ý: Script này sử dụng các lệnh Ceph và các khái niệm cụ thể về Ceph, vì vậy người dùng cần có kiến thức cơ bản về Ceph để sử dụng nó hiệu quả.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories