Sunday, May 4, 2014

Light Weight Monitoring System (LWM) ตอนที่ 4

โพสต์ครั้งแรก: 1 พฤษภาคม 2011

การสร้าง Job เพื่อ Maintain และสร้าง Baseline อัตโนมัติ
วันนี้จะเป็นตอนต่อของการสร้าง LWM แบบ Step-by_Step โดยเมื่อตอนที่แล้วเราได้เตรียมโครงสร้างต่าง ๆ ไว้แล้ว และได้สร้าง Job ที่กำหนดเวลาไว้ให้รันทุก ๆ หนึ่งนาทีเพื่อนำข้อมูลที่เกี่ยวกับ Session เก็บไว้ในตารางก่อนนำมาพล็อตกราฟต่อไป สำหรับวันนี้จะเป็นการเขียนสคริปต์เพื่อ Maintain ข้อมูลในตารางต่าง ๆ ในระบบให้รันได้อย่างมีประสิทธิภาพ ตลอดจนการสร้าง Baseline เก็บไว้ในฐานข้อมูลเพื่อนำมาพล็อตเปรียบเทียบกับข้อมูลปัจจุบัน
Maintain ข้อมูลในตาราง SESS_MON และข้อมูล Baseline ใน SESS_MON_BASE
วิธีการและสคริปต์ต่าง ๆ ที่ระบุไว้ ณ ที่นี้ได้รับการทดสอบแล้วเป็นการภายใน ซึ่งสามารถใช้งานได้ตามที่ระบุไว้ อย่างไรก็ตามเราไม่สามารถรับรองได้ว่าจะได้ผลสำเร็จทุกประการสำหรับผู้อ่าน กรุณาทดสอบในสิ่งแวดล้อมของคุณก่อนที่จะใช้งานจริง

เนื่องจากเราต้องการให้การคิวรีข้อมูลจากตาราง SESS_MON มีประสิทธิภาพที่สุด (เร็วที่สุดและไม่สิ้นเปลืองทรัพยากรระบบ เนื่องจากจะต้องคิวรีตลอดเวลา) เราจะสร้าง Job ขึ้นมาให้ทำการ Purge ข้อมูลใน SESS_MON และนำไปเก็บไว้ใน SESS_MON_HIST แทน เราใช้ข้อมูลใน SESS_MON_HIST ในการสร้าง Baseline โดยการหาค่าเฉลี่ยของค่าที่เราต้องการมอนิเตอร์
  • คำสั่งข้างล่างใช้ในการ Purge ข้อมูลโดยย้ายจาก SESS_MON ไปไว้ที่ SESS_MON_HIST
insert into lwm.sess_mon_hist select * from lwm.sess_mon where sess_time < trunc(sysdate);
delete from lwm.sess_mon where sess_time < trunc(sysdate);
  • คำสั่งที่ใช้ในการสร้าง Baseline ใหม่ โดยการนำเอาข้อมูลจากตาราง SESS_MON_HIST (ซึ่งเก็บข้อมูลย้อนหลังของ Session) ย้อนหลัง 30 วัน นำเฉพาะค่าที่มีความถี่สูง ๆ (อยู่ในช่วง +/- Standard Deviation /2) มาหาค่าเฉลี่ย
insert into lwm.sess_mon_base
select round(avg(sess_cnt)),round(avg(max_last_call_et)),sysdate
from lwm.sess_mon_hist
where sess_time between sysdate-30 and sysdate
and max_last_call_et between
(select avg(max_last_call_et)- stddev(max_last_call_et)/2
from lwm.sess_mon_hist
where sess_time between sysdate-30 and sysdate)
and (select avg(max_last_call_et)+ stddev(max_last_call_et)/2
from lwm.sess_mon_hist
where sess_time between sysdate-30 and sysdate);
คำสั่งที่ใช้ในการ Maintain ทั้งหมดจะถูกนำมาสร้าง Job เพื่อให้ทำการ Maintain ระบบโดยอัตโนมัติตอน 2:00 น. ของทุกวัน
SQL> variable jobno number
SQL> begin
2 dbms_job.submit(:jobno,
3 -- Move data to SESS_MON_HIST
4 'insert into lwm.sess_mon_hist
5 select * from lwm.sess_mon where sess_time < trunc(sysdate);
6 -- Recreate Baseline
7 delete from lwm.sess_mon_base;
8 insert into lwm.sess_mon_base
9 select round(avg(sess_cnt)),round(avg(max_last_call_et)),sysdate
10 from lwm.sess_mon_hist
11 where sess_time between sysdate-30 and sysdate
12 and max_last_call_et between
13 (select avg(max_last_call_et)- stddev(max_last_call_et)/2
14 from lwm.sess_mon_hist
15 where sess_time between sysdate-30 and sysdate)
16 and (select avg(max_last_call_et)+ stddev(max_last_call_et)/2
17 from lwm.sess_mon_hist
18 where sess_time between sysdate-30 and sysdate);
19 -- Clear old data
20 delete from lwm.sess_mon where sess_time < trunc(sysdate);'
21 ,SYSDATE,'TRUNC(SYSDATE+1)+2/24');
22 commit;
23 end;
24 /

PL/SQL procedure successfully completed.
ข้อมูลใน SESS_MON_HIST จะโตขึ้นเรื่อย ๆ วันละ 1440 เรคคอร์ดทุกวัน (60 x 24 = 1440) คุณอาจจะทำ Job อีกตัวที่จะทำการ Aggregate ข้อมูลจากรายนาทีเป็นรายวันแล้วเก็บไว้ในอีกตารางหนึ่ง แล้วจึงลบข้อมูลใน SESS_MON_HIST ที่ได้ทำการ Aggregate แล้วออกไป ด้วยวิธีนี้ข้อมูลในระบบ LWM จะสามารถเก็บไว้ได้เป็น 100 ปี (365 x 10 = 3650 เรคคอร์ด) โดยไม่ต้อง Maintain!

สร้างวิวเพื่อนำข้อมูลมาพล็อตกราฟ
ขั้นตอนสุดท้ายเป็นสร้างวิวที่ใช้ในการเรียกข้อมูลปัจจุบันจาก SESS_MON มาเปรียบเทียบกับ Baseline ใน SESS_MON_BASE ซึ่งเราจะใช้ในการนำไปพล็อตกราฟ
SQL> create or replace view lwm.vw_sess_mon_norm as
2 select to_char(a.sess_time,'hh24:mi') as sess_time
3 ,round(a.sess_cnt/b.sess_cnt_base,2) as sess_cnt_per_base,
4 1 as sess_cnt_base
5 ,round(max_last_call_et/b.max_last_call_et_base,2) as max_last_call_et_per_base,
6 1 as max_last_call_base
7 from lwm.sess_mon a, lwm.sess_mon_base b
8 where a.sess_time between sysdate-1/24 and sysdate
9 order by a.sess_time;

View created.

SQL> select * from lwm.vw_sess_mon_norm;

SESS_ SESS_CNT_PER_BASE SESS_CNT_BASE MAX_LAST_CALL_ET_PER_BASE MAX_LAST_CALL_BASE
----- ----------------- ------------- ------------------------- ------------------
11:59 .67 1 .52 1
12:00 .67 1 703.16 1
12:01 .67 1 .97 1
12:02 .67 1 .97 1
12:03 .67 1 .97 1
12:04 .67 1 .97 1
12:05 .67 1 .97 1


7 rows selected.


SQL> desc lwm.vw_sess_mon_norm;
Name Null? Type
---------------------------- -------- ------------------------------------
SESS_TIME VARCHAR2(5)
SESS_CNT_PER_BASE NUMBER
SESS_CNT_BASE NUMBER
MAX_LAST_CALL_ET_PER_BASE NUMBER
MAX_LAST_CALL_BASE NUMBER

คอลัมน์ต่างๆ มีความหมายดังนี้
ชื่อคอลัมน์ความหมาย
SESS_TIMEเวลา ณ ขณะจับข้อมูล Session
SESS_CNT_PER_BASEจำนวนของ Session ต่อ Baseline ถ้าค่านี้เท่ากับ 1 หมายความว่าจำนวน Session ณ ขณะนั้นมีค่าเท่ากับค่า Baseline
SESS_CNT_BASEค่า Baseline ของ SESS_CNT ค่านี้จะเป็น 1 เสมอ
MAX_LAST_CALL_ET_PER_BASEค่า LAST_CALL_ET สูงสุด ณ ขณะจับข้อมูล เปรียบเทียบกับ Baseline ที่คำนวณได้ ถ้าค่านี้เท่ากับ 1 หมายความว่าค่า LAST_CALL_ET สูงสุด ณ ขณะนั้นมีค่าเท่ากับค่า Baseline
MAX_LAST_CALL_BASEค่า Baseline ของ MAX_LAST_CALL_ET ค่านี้่จะมีค่าเป็น 1 เสมอ

ครั้งหน้าเราจะมาดูกันเรื่องการนำข้อมูลจากวิวขึ้นพล็อตเป็นกราฟบน Excel นะครับ

No comments:

Post a Comment