[บันทึกกันลืม] ห่างหายไปนาน
กำลังทำระบบ ETL ซึ่งเป็นลักษณะของ Concurrent processing โจทย์คือ ต้องเอาข้อมูล 40 ล้าน items เข้าไปใน Apache Cassandra cluster ที่ประกอบด้วย 5 nodes เป้าหมายคือ 1000 items /second
วิธีทำ concurrent ด้วย python เดี๋ยวมาเล่าให้ฟัง (รอ Link ตรงนี้)
โดยย่อ การนำเข้าข้อมูล ทำด้วย Python script แล้วจะเขียน log file หน้าตาประมาณนี้ ให้สนใจแค่ว่าคอลัมน์แรก เป็น timestamp
ประมาณว่า บรรทัดแรก เขียนข้อมูลเมื่อ 2022-11-30 07:34:13
แล้วบรรทัดล่าสุด หน้าตาประมาณนี้
ประมาณว่า บรรทัดสุดท้าย เขียนข้อมูลเมื่อ 2022-11-30 11:12:19
ทำไปแล้วกี่ items ใช้คำสั่ง wc -l นับบรรทัด เก็บในตัวแปร it
wc -l kx.log
ได้มาประมาณ 17,030,016 items
แล้วเราจะหา จำนวนวินาที จากเริ่มต้น ถึงปัจจุบันอย่างไร ???
อันนี้คือ shell script เดี๋ยวอธิบายต่อไป
t1=$(head -1 kx.log|cut -d, -f1); ts1=$(date -d "$t1" +%s); t2=$(tail -1 kx.log|cut -d, -f1); ts2=$(date -d "$t2" +%s); it=$(wc -l kx.log|cut -d' ' -f1); retrys=$(wc -l retryf.txt| cut -d' ' -f1); ss=$(expr $ts2 - $ts1) ; timelag=$(date -d@$ss -u +%H:%M:%S); speed=$(expr \( $it - $retrys \) / \( $ts2 - $ts1 \)); echo "process $it items, take $timelag, $speed it/s"
เมื่อ run แล้ว ได้ผลลัพธ์ประมาณนี้
process 17030016 items, 1334 it/s
มาดูรายละเอียดกัน
t1=$(head -1 kx.log|cut -d, -f1)
เป็นการสร้างตัวแปร ชื่อ t1 ซึ่ง $(…) เป็นการสั่งให้คำสั่ง ภายในวงเล็บ นั้นทำงาน
head -1 kx.log
คำสั่ง head -1 คือ เอาบรรทัดแรก
cut -d, -f1
เป็นการ แยกข้อความ ด้วย , และเอา ฟิลด์ (field) ที่ 1 ออกมา
ผลรวมของคำสั่งนี้ คือ จะได้ timestamp เก็บในตัวแปร t1
2022-11-30 07:34:13
เช่นเดียวกับเวลาของบรรทัดสุดท้าย เปลี่ยนจาก head เป็น tail ก็จะได้ ตัวแปร t2
2022-11-30 11:12:19
คราวนี้ เราจะรู้ได้ไง ว่า ระหว่าง 2022-11-30 07:34:13 กับ 2022-11-30 11:12:19 ห่างกันกี่วินาที ?
เราสามารถใช้คำสั่ง (เก็บในตัวแปร ts2)
date -d '2022-11-30 11:12:19' +%s
เพื่อได้วินาทีของวันเวลา คือค่า
1669781539
เช่นดัวกับ เวลาเริ่มต้น (เก็บในตัวแปร ts1)
date -d '2022-11-30 07:34:13' +%s
จะได้ค่า
1669768453
มาถึงตรงนี้ เราก็จะได้ตัวแปร ts1, ts2, it เราจะหาความเร็วก็ต้องใช้สูตร
speed = it / (ts2 - ts1)
ใน shell script เราเขียนตรง ๆ อย่างนั้นไม่ได้ ต้องใช้ผ่านคำสั่ง expr (เก็บในตัวแปร speed)
expr $it / \( $ts2 - $ts1 \)
คราวนี้ เราต้องการรู้ด้วยว่า ใช้เวลาทำไปแล้ว กี่ชั่วโมง นาที วินาที คำสั่งนี้ ใช้ date -d แล้วใช้ @ ตามด้วยจำนวนวินาที
date -d@60 -u +%H:%M:%S
ใช้คำสั่งนี้ หา จำนวนวินาที เก็บในตัวแปร ss
expr $ts2 - $ts1
แล้วใช้คำสั่งนี้ แปลงเป็น ชั่วโมง นาที วินาที เก็บในตัวแปร timelag
date -d@$ss -u +%H:%M:%S
สุดท้าย เอามารวมกันทั้งหมด แล้ว echo ออกไป
echo "process $it items, take $timelag, $speed it/s"
ผลที่ได้คือ
process 17030016 items, take 04:29:03, 1334 it/s
หวังว่าจะเป็นประโยชน์ครับ