สวัสดี
ฉันตัดสินใจแบ่งปันสิ่งที่ฉันค้นพบ - ผลของความคิด การลองผิดลองถูก
โดยทั่วไปแล้ว: แน่นอนว่านี่ไม่ใช่การค้นพบ - ทั้งหมดนี้ควรรู้มานานแล้วสำหรับผู้ที่มีส่วนร่วมในการประมวลผลข้อมูลทางสถิติประยุกต์และการเพิ่มประสิทธิภาพของระบบใด ๆ โดยไม่จำเป็นต้องเป็น DBMS โดยเฉพาะ
และใช่ พวกเขารู้ พวกเขาเขียนบทความที่น่าสนใจเกี่ยวกับงานวิจัยของพวกเขา
ในทางกลับกัน: ทันที ฉันไม่เห็นการกล่าวถึงหรือการเผยแพร่แนวทางนี้อย่างกว้างขวางบนอินเทอร์เน็ตในหมู่ผู้เชี่ยวชาญด้านไอที DBA
ดังนั้นตรงประเด็น
สมมติว่าเรามีงาน: ตั้งค่าระบบบริการบางอย่างเพื่อให้บริการงานบางประเภท
งานนี้เป็นที่รู้จัก: มันคืออะไร, วัดคุณภาพของงานนี้อย่างไร, และอะไรเป็นเกณฑ์ในการวัดคุณภาพนี้
สมมติว่าเป็นที่รู้จักและเข้าใจไม่มากก็น้อย: วิธีการทำงานใน (หรือร่วมกับ) ระบบบริการนี้
“มากหรือน้อย” - หมายความว่ามีความเป็นไปได้ที่จะเตรียม (หรือได้รับจากที่อื่น) เครื่องมือ อรรถประโยชน์ บริการบางอย่างที่สามารถสังเคราะห์และนำไปใช้กับระบบโดยมีโหลดทดสอบเพียงพอกับสิ่งที่จะเกิดขึ้นในการผลิต ในสภาวะที่เพียงพอต่อการทำงานในการผลิต
สมมติว่าชุดของพารามิเตอร์การปรับสำหรับระบบบริการนี้เป็นที่รู้จักซึ่งสามารถใช้ในการกำหนดค่าระบบนี้ในแง่ของประสิทธิภาพการทำงานของระบบ
และปัญหาคืออะไร - ไม่มีความเข้าใจที่สมบูรณ์เพียงพอเกี่ยวกับระบบบริการนี้ ซึ่งช่วยให้คุณสามารถกำหนดการตั้งค่าของระบบนี้อย่างเชี่ยวชาญสำหรับการโหลดในอนาคตบนแพลตฟอร์มที่กำหนดและรับประสิทธิภาพการทำงานที่ต้องการของระบบ
ดี. นี่เป็นกรณีเกือบทุกครั้ง
คุณสามารถทำอะไรที่นี่?
สิ่งแรกที่นึกถึงคือการดูเอกสารประกอบสำหรับระบบนี้ ทำความเข้าใจว่าช่วงที่ยอมรับได้คือค่าของพารามิเตอร์การปรับค่าใด และตัวอย่างเช่น เมื่อใช้วิธีการลดพิกัด ให้เลือกค่าสำหรับพารามิเตอร์ระบบในการทดสอบ
เหล่านั้น. ให้การกำหนดค่าบางอย่างแก่ระบบในรูปแบบของชุดค่าเฉพาะสำหรับพารามิเตอร์การกำหนดค่า
ใช้โหลดทดสอบกับโหลดโดยใช้ยูทิลิตี้เครื่องมือตัวสร้างโหลดนี้
และดูที่ค่า-การตอบสนองหรือตัวชี้วัดคุณภาพของระบบ
ความคิดที่สองอาจเป็นข้อสรุปว่านี่เป็นเวลานานมาก
นั่นคือ: หากมีพารามิเตอร์การปรับแต่งจำนวนมากหากช่วงของค่าที่ครอบคลุมมีขนาดใหญ่หากการทดสอบโหลดแต่ละครั้งใช้เวลานานมากในการทำให้เสร็จสิ้น: ใช่ทั้งหมดนี้อาจใช้จำนวนที่ยอมรับไม่ได้ ของเวลา
นี่คือสิ่งที่คุณสามารถเข้าใจและจดจำได้
คุณจะพบว่าในชุดค่าของพารามิเตอร์การตั้งค่าระบบบริการจะมีเวกเตอร์เป็นลำดับของค่าบางค่า
เวกเตอร์แต่ละตัว หรือสิ่งอื่นๆ ที่เท่ากัน (โดยที่ไม่ได้รับผลกระทบจากเวกเตอร์นี้) สอดคล้องกับค่าเมตริกที่แน่นอนซึ่งเป็นตัวบ่งชี้คุณภาพของการทำงานของระบบภายใต้โหลดทดสอบ
เช่น
ให้เราแสดงว่าเวกเตอร์การกำหนดค่าระบบเป็น ที่ไหน ; ที่ไหน — จำนวนพารามิเตอร์การกำหนดค่าระบบ จำนวนพารามิเตอร์เหล่านี้
และค่าของเมตริกที่สอดคล้องกับสิ่งนี้ ลองแสดงว่ามันเป็น
จากนั้นเราจะได้ฟังก์ชัน:
ในกรณีของฉัน ทุกสิ่งจะเกิดขึ้นทันที: เกือบลืมไปแล้วตั้งแต่สมัยเรียน อัลกอริธึมสำหรับการค้นหาส่วนปลายสุดของฟังก์ชัน
โอเค แต่ที่นี่มีคำถามเกี่ยวกับองค์กรและการประยุกต์ใช้: อัลกอริทึมที่จะใช้
- ในแง่หนึ่ง - เพื่อให้คุณสามารถเขียนโค้ดน้อยลงด้วยมือ
- และเพื่อให้มันได้ผลนั่นคือ พบจุดสุดยอด (ถ้ามี) อย่างน้อยก็เร็วกว่าการโคลงพิกัด
ประเด็นแรกบอกเป็นนัยว่าเราต้องพิจารณาสภาพแวดล้อมบางอย่างที่มีการนำอัลกอริธึมดังกล่าวไปใช้แล้ว และในบางรูปแบบ ก็พร้อมสำหรับใช้ในโค้ดแล้ว
ฉันรู้ python
и cran-r
ประเด็นที่สองหมายความว่าคุณต้องอ่านเกี่ยวกับอัลกอริธึมด้วยตนเอง ว่าอัลกอริธึมคืออะไร ข้อกำหนดคืออะไร และคุณลักษณะของงาน
และสิ่งที่พวกเขาให้อาจเป็นผลข้างเคียงที่เป็นประโยชน์ - ผลลัพธ์หรือโดยตรงจากอัลกอริทึมเอง
หรือสามารถหาได้จากผลลัพธ์ของอัลกอริทึม
มากขึ้นอยู่กับเงื่อนไขอินพุต
ตัวอย่างเช่น หากคุณต้องการได้ผลลัพธ์เร็วขึ้นด้วยเหตุผลบางประการ คุณต้องดูอัลกอริธึมการไล่ระดับสีและเลือกหนึ่งในนั้น
หรือหากเวลาไม่สำคัญมากนัก คุณสามารถใช้วิธีการสุ่มเพิ่มประสิทธิภาพ เช่น อัลกอริธึมทางพันธุกรรม เป็นต้น
ฉันเสนอให้พิจารณาการทำงานของแนวทางนี้โดยเลือกการกำหนดค่าระบบโดยใช้อัลกอริธึมทางพันธุกรรมในครั้งต่อไปเพื่อพูด: งานในห้องปฏิบัติการ
ต้นฉบับ:
- ให้มีเป็นระบบบริการ:
oracle xe 18c
- ปล่อยให้รองรับกิจกรรมการทำธุรกรรมและเป้าหมาย: เพื่อให้ได้ปริมาณงานฐานข้อมูลย่อยที่สูงที่สุดเท่าที่จะเป็นไปได้ในหน่วยธุรกรรม/วินาที
- ธุรกรรมอาจแตกต่างกันมากในลักษณะการทำงานกับข้อมูลและบริบทของงาน
ยอมรับว่าธุรกรรมเหล่านี้เป็นธุรกรรมที่ไม่ได้ประมวลผลข้อมูลแบบตารางจำนวนมาก
ในแง่ที่ว่าพวกเขาไม่ได้สร้างข้อมูลการเลิกทำมากกว่าการทำซ้ำ และไม่ประมวลผลแถวและตารางขนาดใหญ่ในเปอร์เซ็นต์ที่สูง
ธุรกรรมเหล่านี้เป็นธุรกรรมที่เปลี่ยนแปลงหนึ่งแถวในตารางที่มีขนาดใหญ่ไม่มากก็น้อย โดยมีดัชนีจำนวนเล็กน้อยในตารางนี้
ในสถานการณ์นี้: ประสิทธิภาพของฐานข้อมูลย่อยสำหรับการประมวลผลธุรกรรมจะถูกกำหนดโดยคุณภาพของการประมวลผลโดยฐานข้อมูลรีดอกซ์โดยมีการสำรองไว้
ข้อจำกัดความรับผิดชอบ - หากเราพูดถึงการตั้งค่า subdb โดยเฉพาะ
เนื่องจากในกรณีทั่วไป อาจมี ตัวอย่างเช่น การล็อกธุรกรรมระหว่างเซสชัน SQL เนื่องจากการออกแบบการทำงานของผู้ใช้กับข้อมูลแบบตารางและ/หรือแบบจำลองแบบตาราง
ซึ่งแน่นอนว่าจะมีผลกระทบต่อการวัด TPS และนี่จะเป็นปัจจัยภายนอกที่สัมพันธ์กับฐานข้อมูลย่อย: นี่คือวิธีการออกแบบแบบจำลองแบบตารางและการทำงานกับข้อมูลในนั้นที่เกิดการอุดตัน
ดังนั้นเพื่อความบริสุทธิ์ของการทดลอง เราจะแยกปัจจัยนี้ออก และฉันจะชี้แจงด้านล่างอย่างชัดเจนว่าอย่างไร
- ให้เราถือว่า 100% ของคำสั่ง SQL ที่ส่งไปยังฐานข้อมูลนั้นเป็นคำสั่ง DML
ให้คุณลักษณะของผู้ใช้ทำงานกับฐานข้อมูลย่อยเหมือนกันในการทดสอบ
กล่าวคือ จำนวนเซสชัน skl ข้อมูลแบบตาราง วิธีการทำงานของเซสชัน skl - งานย่อยใน
FORCE LOGGING
,ARCHIVELOG
ม็อด โหมดฐานข้อมูล Flashback ถูกปิดที่ระดับย่อย - ทำซ้ำบันทึก: อยู่ในระบบไฟล์แยกต่างหากบน "ดิสก์" แยกต่างหาก
ส่วนที่เหลือขององค์ประกอบทางกายภาพของฐานข้อมูล: ในระบบไฟล์อื่นที่แยกจากกันบน "ดิสก์" แยกต่างหาก:
รายละเอียดเพิ่มเติมเกี่ยวกับอุปกรณ์ทางกายภาพ ส่วนประกอบฐานข้อมูลห้องปฏิบัติการ
SQL> select status||' '||name from v$controlfile;
/db/u14/oradata/XE/control01.ctl
SQL> select GROUP#||' '||MEMBER from v$logfile;
1 /db/u02/oradata/XE/redo01_01.log
2 /db/u02/oradata/XE/redo02_01.log
SQL> select FILE_ID||' '||TABLESPACE_NAME||' '||round(BYTES/1024/1024,2)||' '||FILE_NAME as col from dba_data_files;
4 UNDOTBS1 2208 /db/u14/oradata/XE/undotbs1_01.dbf
2 SLOB 128 /db/u14/oradata/XE/slob01.dbf
7 USERS 5 /db/u14/oradata/XE/users01.dbf
1 SYSTEM 860 /db/u14/oradata/XE/system01.dbf
3 SYSAUX 550 /db/u14/oradata/XE/sysaux01.dbf
5 MONITOR 128 /db/u14/oradata/XE/monitor.dbf
SQL> !cat /proc/mounts | egrep "/db/u[0-2]"
/dev/vda1 /db/u14 ext4 rw,noatime,nodiratime,data=ordered 0 0
/dev/mapper/vgsys-ora_redo /db/u02 xfs rw,noatime,nodiratime,attr2,nobarrier,inode64,logbsize=256k,noquota 0 0
เริ่มแรก ภายใต้เงื่อนไขโหลดเหล่านี้ ฉันต้องการใช้ธุรกรรมย่อย
มันมีคุณสมบัติที่ยอดเยี่ยมมาก ฉันจะอ้างอิงถึงผู้เขียน:
หัวใจของ SLOB คือ “วิธี SLOB” วิธี SLOB มีวัตถุประสงค์เพื่อทดสอบแพลตฟอร์ม
โดยไม่มีข้อโต้แย้งในการสมัคร ไม่มีใครสามารถขับเคลื่อนประสิทธิภาพฮาร์ดแวร์สูงสุดได้
การใช้รหัสแอปพลิเคชันที่ผูกมัดโดยการล็อคแอปพลิเคชันหรือแม้แต่
การแชร์บล็อกฐานข้อมูล Oracle ใช่แล้ว การแบ่งปันข้อมูลมีค่าใช้จ่าย
ในบล็อกข้อมูล! แต่ SLOB—ในการปรับใช้เริ่มต้น—จะรอดพ้นจากความขัดแย้งดังกล่าว
คำประกาศนี้: สอดคล้องกัน มันคือ
สะดวกในการควบคุมระดับความขนานของเซสชัน cl นี่คือกุญแจสำคัญ -t
เปิดยูทิลิตี้ runit.sh
จาก สลอฟ
เปอร์เซ็นต์ของคำสั่ง DML ได้รับการควบคุม ในจำนวนข้อความที่ส่งไปยังส่วนย่อย แต่ละเซสชันข้อความ พารามิเตอร์ UPDATE_PCT
แยกจากกันและสะดวกมาก: SLOB
ก่อนและหลังเซสชันการโหลด - เตรียม statspack หรือ awr-snapshots (สิ่งที่ตั้งค่าไว้ให้เตรียม)
อย่างไรก็ตาม มันกลับกลายเป็นว่า SLOB
ไม่รองรับเซสชัน SQL ที่มีระยะเวลาน้อยกว่า 30 วินาที
ดังนั้นฉันจึงเขียนโค้ดตัวโหลดเวอร์ชันคนงาน - ชาวนาของตัวเองก่อนจากนั้นจึงยังคงทำงานต่อไป
ฉันขอชี้แจงว่าตัวโหลดทำอะไรและทำอย่างไรเพื่อความชัดเจน
โดยพื้นฐานแล้วตัวโหลดจะมีลักษณะดังนี้:
รหัสพนักงาน
function dotx()
{
local v_period="$2"
[ -z "v_period" ] && v_period="0"
source "/home/oracle/testingredotracе/config.conf"
$ORACLE_HOME/bin/sqlplus -S system/${v_system_pwd} << __EOF__
whenever sqlerror exit failure
set verify off
set echo off
set feedback off
define wnum="$1"
define period="$v_period"
set appinfo worker_&&wnum
declare
v_upto number;
v_key number;
v_tots number;
v_cts number;
begin
select max(col1) into v_upto from system.testtab_&&wnum;
SELECT (( SYSDATE - DATE '1970-01-01' ) * 86400 ) into v_cts FROM DUAL;
v_tots := &&period + v_cts;
while v_cts <= v_tots
loop
v_key:=abs(mod(dbms_random.random,v_upto));
if v_key=0 then
v_key:=1;
end if;
update system.testtab_&&wnum t
set t.object_name=translate(dbms_random.string('a', 120), 'abcXYZ', '158249')
where t.col1=v_key
;
commit;
SELECT (( SYSDATE - DATE '1970-01-01' ) * 86400 ) into v_cts FROM DUAL;
end loop;
end;
/
exit
__EOF__
}
export -f dotx
คนงานถูกเปิดตัวด้วยวิธีนี้:
วิ่งคนงาน
echo "starting test, duration: ${TEST_DURATION}" >> "$v_logfile"
for((i=1;i<="$SQLSESS_COUNT";i++))
do
echo "sql-session: ${i}" >> "$v_logfile"
dotx "$i" "${TEST_DURATION}" &
done
echo "waiting..." >> "$v_logfile"
wait
และโต๊ะสำหรับคนงานก็เตรียมไว้ดังนี้:
การสร้างตาราง
function createtable() {
source "/home/oracle/testingredotracе/config.conf"
$ORACLE_HOME/bin/sqlplus -S system/${v_system_pwd} << __EOF__
whenever sqlerror continue
set verify off
set echo off
set feedback off
define wnum="$1"
define ts_name="slob"
begin
execute immediate 'drop table system.testtab_&&wnum';
exception when others then null;
end;
/
create table system.testtab_&&wnum tablespace &&ts_name as
select rownum as col1, t.*
from sys.dba_objects t
where rownum<1000
;
create index testtab_&&wnum._idx on system.testtab_&&wnum (col1);
--alter table system.testtab_&&wnum nologging;
--alter index system.testtab_&&wnum._idx nologging;
exit
__EOF__
}
export -f createtable
seq 1 1 "$SQLSESS_COUNT" | xargs -n 1 -P 4 -I {} -t bash -c "createtable "{}"" | tee -a "$v_logfile"
echo "createtable done" >> "$v_logfile"
เหล่านั้น. สำหรับผู้ปฏิบัติงานแต่ละคน (ในทางปฏิบัติ: เซสชัน SQL แยกกันในฐานข้อมูล) จะมีการสร้างตารางแยกกัน ซึ่งผู้ปฏิบัติงานทำงานด้วย
เพื่อให้แน่ใจว่าไม่มีการล็อกธุรกรรมระหว่างเซสชันของผู้ปฏิบัติงาน
คนงานแต่ละคน: ทำสิ่งเดียวกันกับโต๊ะของเขาเอง โต๊ะก็เหมือนกันหมด
คนงานทุกคนปฏิบัติงานในระยะเวลาเท่ากัน
ยิ่งไปกว่านั้น เป็นเวลานานพอสมควรที่ตัวอย่างเช่น สวิตช์บันทึกจะเกิดขึ้นอย่างแน่นอน และมากกว่าหนึ่งครั้ง
ด้วยเหตุนี้ต้นทุนและผลกระทบที่เกี่ยวข้องจึงเกิดขึ้น
ในกรณีของฉัน ฉันกำหนดระยะเวลาการทำงานของคนงานไว้ที่ 8 นาที
รายงาน statspack ส่วนหนึ่งที่อธิบายการทำงานของส่วนย่อยที่กำลังโหลด
Database DB Id Instance Inst Num Startup Time Release RAC
~~~~~~~~ ----------- ------------ -------- --------------- ----------- ---
2929910313 XE 1 07-Sep-20 23:12 18.0.0.0.0 NO
Host Name Platform CPUs Cores Sockets Memory (G)
~~~~ ---------------- ---------------------- ----- ----- ------- ------------
billing.izhevsk1 Linux x86 64-bit 2 2 1 15.6
Snapshot Snap Id Snap Time Sessions Curs/Sess Comment
~~~~~~~~ ---------- ------------------ -------- --------- ------------------
Begin Snap: 1630 07-Sep-20 23:12:27 55 .7
End Snap: 1631 07-Sep-20 23:20:29 62 .6
Elapsed: 8.03 (mins) Av Act Sess: 8.4
DB time: 67.31 (mins) DB CPU: 15.01 (mins)
Cache Sizes Begin End
~~~~~~~~~~~ ---------- ----------
Buffer Cache: 1,392M Std Block Size: 8K
Shared Pool: 288M Log Buffer: 103,424K
Load Profile Per Second Per Transaction Per Exec Per Call
~~~~~~~~~~~~ ------------------ ----------------- ----------- -----------
DB time(s): 8.4 0.0 0.00 0.20
DB CPU(s): 1.9 0.0 0.00 0.04
Redo size: 7,685,765.6 978.4
Logical reads: 60,447.0 7.7
Block changes: 47,167.3 6.0
Physical reads: 8.3 0.0
Physical writes: 253.4 0.0
User calls: 42.6 0.0
Parses: 23.2 0.0
Hard parses: 1.2 0.0
W/A MB processed: 1.0 0.0
Logons: 0.5 0.0
Executes: 15,756.5 2.0
Rollbacks: 0.0 0.0
Transactions: 7,855.1
กลับมาที่งานห้องปฏิบัติการ
เราจะเปลี่ยนแปลงค่าของพารามิเตอร์ต่อไปนี้ของฐานข้อมูลย่อยของห้องปฏิบัติการ:
- ขนาดของกลุ่มบันทึกฐานข้อมูล ช่วงค่า: [32, 1024] MB;
- จำนวนกลุ่มเจอร์นัลในฐานข้อมูล ช่วงค่า: [2,32];
log_archive_max_processes
ช่วงค่า: [1,8];commit_logging
อนุญาตให้ใช้สองค่า:batch|immediate
;commit_wait
อนุญาตให้ใช้สองค่า:wait|nowait
;log_buffer
ช่วงค่า: [2,128] MBlog_checkpoint_timeout
ช่วงค่า: [60,1200] วินาทีdb_writer_processes
ช่วงค่า: [1,4]undo_retention
ช่วงค่า: [30;300] วินาทีtransactions_per_rollback_segment
ช่วงค่า: [1,8]disk_asynch_io
อนุญาตให้ใช้สองค่า:true|false
;filesystemio_options
อนุญาตให้ใช้ค่าต่อไปนี้:none|setall|directIO|asynch
;db_block_checking
อนุญาตให้ใช้ค่าต่อไปนี้:OFF|LOW|MEDIUM|FULL
;db_block_checksum
อนุญาตให้ใช้ค่าต่อไปนี้:OFF|TYPICAL|FULL
;
ผู้ที่มีประสบการณ์ในการบำรุงรักษาฐานข้อมูล Oracle สามารถพูดได้อย่างแน่นอนว่าควรตั้งค่าอะไรและค่าใดจากพารามิเตอร์ที่ระบุและค่าที่ยอมรับได้เพื่อให้ได้ประสิทธิผลของฐานข้อมูลมากขึ้นสำหรับการทำงานกับข้อมูลที่ระบุโดย รหัสแอปพลิเคชัน ที่นี่ด้านบน
แต่
จุดประสงค์ของงานในห้องปฏิบัติการคือการแสดงให้เห็นว่าอัลกอริธึมการปรับให้เหมาะสมจะช่วยชี้แจงสิ่งนี้ให้เราได้ค่อนข้างเร็ว
สำหรับเรา สิ่งที่เหลืออยู่คือการพิจารณาเอกสารผ่านระบบที่ปรับแต่งได้ เพียงเพียงพอที่จะค้นหาว่าพารามิเตอร์ใดที่ต้องเปลี่ยนแปลงและอยู่ในช่วงใด
และยัง: โค้ดโค้ดที่จะใช้ทำงานกับระบบที่กำหนดเองของอัลกอริธึมการปรับให้เหมาะสมที่เลือก
ตอนนี้เกี่ยวกับรหัส
ฉันได้พูดคุยข้างต้นเกี่ยวกับ cran-r
กล่าวคือ: การปรับแต่งทั้งหมดด้วยระบบที่ปรับแต่งจะถูกจัดเตรียมในรูปแบบของสคริปต์ R
งานจริง การวิเคราะห์ การเลือกตามค่าเมตริก เวกเตอร์สถานะระบบ: นี่คือแพ็คเกจ GA
(
ในกรณีนี้ แพ็คเกจนี้ไม่เหมาะสมนักในแง่ที่คาดว่าเวกเตอร์ (โครโมโซมหากเป็นแพ็คเกจ) จะถูกระบุในรูปแบบของสตริงตัวเลขที่มีเศษส่วน
และเวกเตอร์ของฉันจากค่าของพารามิเตอร์การตั้งค่า: เหล่านี้คือปริมาณ 14 ปริมาณ - จำนวนเต็มและค่าสตริง
แน่นอนว่าปัญหาสามารถหลีกเลี่ยงได้อย่างง่ายดายโดยการกำหนดตัวเลขเฉพาะให้กับค่าสตริง
ดังนั้น ในท้ายที่สุด ส่วนหลักของสคริปต์ R จะมีลักษณะดังนี้:
โทร จีเอ::กา
cat( "", file=v_logfile, sep="n", append=F)
pSize = 10
elitism_value=1
pmutation_coef=0.8
pcrossover_coef=0.1
iterations=50
gam=GA::ga(type="real-valued", fitness=evaluate,
lower=c(32,2, 1,1,1,2,60,1,30,1,0,0, 0,0), upper=c(1024,32, 8,10,10,128,800,4,300,8,10,40, 40,30),
popSize=pSize,
pcrossover = pcrossover_coef,
pmutation = pmutation_coef,
maxiter=iterations,
run=4,
keepBest=T)
cat( "GA-session is done" , file=v_logfile, sep="n", append=T)
gam@solution
ที่นี่ด้วยความช่วยเหลือ lower
и upper
คุณลักษณะรูทีนย่อย ga
โดยพื้นฐานแล้วจะมีการระบุพื้นที่ของพื้นที่การค้นหาซึ่งจะทำการค้นหาสำหรับเวกเตอร์ (หรือเวกเตอร์) ดังกล่าวซึ่งจะได้รับค่าสูงสุดของฟังก์ชันฟิตเนส
รูทีนย่อย ga ดำเนินการค้นหาเพื่อเพิ่มฟังก์ชันฟิตเนสให้สูงสุด
ปรากฎว่าในกรณีนี้จำเป็นที่ฟังก์ชันฟิตเนสซึ่งเข้าใจเวกเตอร์เป็นชุดของค่าสำหรับพารามิเตอร์บางตัวของ subd จะต้องได้รับเมตริกจาก subd
นั่นคือ: จำนวนที่มีการตั้งค่าย่อยที่กำหนดและโหลดที่กำหนดใน subd: subd ประมวลผลธุรกรรมต่อวินาที
นั่นคือเมื่อกางออก จะต้องดำเนินการหลายขั้นตอนต่อไปนี้ภายในฟังก์ชันฟิตเนส:
- กำลังประมวลผลเวกเตอร์อินพุตของตัวเลข - แปลงเป็นค่าสำหรับพารามิเตอร์ข้อมูลย่อย
- ความพยายามที่จะสร้างกลุ่มทำซ้ำในขนาดที่กำหนดตามจำนวนที่กำหนด ยิ่งกว่านั้นความพยายามอาจไม่สำเร็จ
กลุ่มนิตยสารที่มีอยู่แล้วในกลุ่มย่อย ในปริมาณหนึ่งและบางขนาด เพื่อความบริสุทธิ์ของการทดลอง - d.b. ลบแล้ว - หากจุดก่อนหน้าสำเร็จ: ระบุค่าของพารามิเตอร์การกำหนดค่าให้กับฐานข้อมูล (อีกครั้ง: อาจมีความล้มเหลว)
- หากขั้นตอนก่อนหน้าสำเร็จ: การหยุด subd เริ่มต้น subd เพื่อให้ค่าพารามิเตอร์ที่ระบุใหม่มีผล (อีกครั้ง: อาจมีข้อผิดพลาด)
- หากขั้นตอนก่อนหน้าสำเร็จ: ทำการทดสอบโหลด รับเมตริกจาก subd
- คืน subd กลับสู่สถานะดั้งเดิมเช่น ลบกลุ่มบันทึกเพิ่มเติม คืนการกำหนดค่าฐานข้อมูลย่อยเดิมให้ใช้งานได้
รหัสฟังก์ชั่นฟิตเนส
evaluate=function(p_par) {
v_module="evaluate"
v_metric=0
opn=NULL
opn$rg_size=round(p_par[1],digit=0)
opn$rg_count=round(p_par[2],digit=0)
opn$log_archive_max_processes=round(p_par[3],digit=0)
opn$commit_logging="BATCH"
if ( round(p_par[4],digit=0) > 5 ) {
opn$commit_logging="IMMEDIATE"
}
opn$commit_logging=paste("'", opn$commit_logging, "'",sep="")
opn$commit_wait="WAIT"
if ( round(p_par[5],digit=0) > 5 ) {
opn$commit_wait="NOWAIT"
}
opn$commit_wait=paste("'", opn$commit_wait, "'",sep="")
opn$log_buffer=paste(round(p_par[6],digit=0),"m",sep="")
opn$log_checkpoint_timeout=round(p_par[7],digit=0)
opn$db_writer_processes=round(p_par[8],digit=0)
opn$undo_retention=round(p_par[9],digit=0)
opn$transactions_per_rollback_segment=round(p_par[10],digit=0)
opn$disk_asynch_io="true"
if ( round(p_par[11],digit=0) > 5 ) {
opn$disk_asynch_io="false"
}
opn$filesystemio_options="none"
if ( round(p_par[12],digit=0) > 10 && round(p_par[12],digit=0) <= 20 ) {
opn$filesystemio_options="setall"
}
if ( round(p_par[12],digit=0) > 20 && round(p_par[12],digit=0) <= 30 ) {
opn$filesystemio_options="directIO"
}
if ( round(p_par[12],digit=0) > 30 ) {
opn$filesystemio_options="asynch"
}
opn$db_block_checking="OFF"
if ( round(p_par[13],digit=0) > 10 && round(p_par[13],digit=0) <= 20 ) {
opn$db_block_checking="LOW"
}
if ( round(p_par[13],digit=0) > 20 && round(p_par[13],digit=0) <= 30 ) {
opn$db_block_checking="MEDIUM"
}
if ( round(p_par[13],digit=0) > 30 ) {
opn$db_block_checking="FULL"
}
opn$db_block_checksum="OFF"
if ( round(p_par[14],digit=0) > 10 && round(p_par[14],digit=0) <= 20 ) {
opn$db_block_checksum="TYPICAL"
}
if ( round(p_par[14],digit=0) > 20 ) {
opn$db_block_checksum="FULL"
}
v_vector=paste(round(p_par[1],digit=0),round(p_par[2],digit=0),round(p_par[3],digit=0),round(p_par[4],digit=0),round(p_par[5],digit=0),round(p_par[6],digit=0),round(p_par[7],digit=0),round(p_par[8],digit=0),round(p_par[9],digit=0),round(p_par[10],digit=0),round(p_par[11],digit=0),round(p_par[12],digit=0),round(p_par[13],digit=0),round(p_par[14],digit=0),sep=";")
cat( paste(v_module," try to evaluate vector: ", v_vector,sep="") , file=v_logfile, sep="n", append=T)
rc=make_additional_rgroups(opn)
if ( rc!=0 ) {
cat( paste(v_module,"make_additional_rgroups failed",sep="") , file=v_logfile, sep="n", append=T)
return (0)
}
v_rc=0
rc=set_db_parameter("log_archive_max_processes", opn$log_archive_max_processes)
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("commit_logging", opn$commit_logging )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("commit_wait", opn$commit_wait )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("log_buffer", opn$log_buffer )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("log_checkpoint_timeout", opn$log_checkpoint_timeout )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("db_writer_processes", opn$db_writer_processes )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("undo_retention", opn$undo_retention )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("transactions_per_rollback_segment", opn$transactions_per_rollback_segment )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("disk_asynch_io", opn$disk_asynch_io )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("filesystemio_options", opn$filesystemio_options )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("db_block_checking", opn$db_block_checking )
if ( rc != 0 ) { v_rc=1 }
rc=set_db_parameter("db_block_checksum", opn$db_block_checksum )
if ( rc != 0 ) { v_rc=1 }
if ( rc!=0 ) {
cat( paste(v_module," can not startup db with that vector of settings",sep="") , file=v_logfile, sep="n", append=T)
rc=stop_db("immediate")
rc=create_spfile()
rc=start_db("")
rc=remove_additional_rgroups(opn)
return (0)
}
rc=stop_db("immediate")
rc=start_db("")
if ( rc!=0 ) {
cat( paste(v_module," can not startup db with that vector of settings",sep="") , file=v_logfile, sep="n", append=T)
rc=stop_db("abort")
rc=create_spfile()
rc=start_db("")
rc=remove_additional_rgroups(opn)
return (0)
}
rc=run_test()
v_metric=getmetric()
rc=stop_db("immediate")
rc=create_spfile()
rc=start_db("")
rc=remove_additional_rgroups(opn)
cat( paste("result: ",v_metric," ",v_vector,sep="") , file=v_logfile, sep="n", append=T)
return (v_metric)
}
ที่. งานทั้งหมด: ดำเนินการในฟังก์ชันฟิตเนส
รูทีนย่อย ga ประมวลผลเวกเตอร์หรือโครโมโซมที่ถูกต้องกว่า
โดยสิ่งที่สำคัญที่สุดสำหรับเราคือการเลือกโครโมโซมที่มียีนซึ่งฟังก์ชันฟิตเนสให้ค่าที่มาก
โดยพื้นฐานแล้ว นี่คือกระบวนการค้นหาชุดโครโมโซมที่เหมาะสมที่สุดโดยใช้เวกเตอร์ในพื้นที่การค้นหา N มิติ
ชัดเจนมาก มีรายละเอียดมาก
ฉันต้องการแยกประเด็นทางเทคนิคสองประเด็นออกจากกัน
สายเสริมจากฟังก์ชั่น evaluate
ตัวอย่างเช่น การหยุด-เริ่มต้น การตั้งค่าของพารามิเตอร์ย่อย จะดำเนินการตาม cran-r
ฟังก์ชั่น system2
ด้วยความช่วยเหลือซึ่ง: สคริปต์ทุบตีหรือคำสั่งบางอย่างถูกเรียก
ตัวอย่างเช่น:
set_db_parameter
set_db_parameter=function(p1, p2) {
v_module="set_db_parameter"
v_cmd="/home/oracle/testingredotracе/set_db_parameter.sh"
v_args=paste(p1," ",p2,sep="")
x=system2(v_cmd, args=v_args, stdout=T, stderr=T, wait=T)
if ( length(attributes(x)) > 0 ) {
cat(paste(v_module," failed with: ",attributes(x)$status," ",v_cmd," ",v_args,sep=""), file=v_logfile, sep="n", append=T)
return (attributes(x)$status)
}
else {
cat(paste(v_module," ok: ",v_cmd," ",v_args,sep=""), file=v_logfile, sep="n", append=T)
return (0)
}
}
จุดที่สองคือเส้น evaluate
ฟังก์ชั่นพร้อมการบันทึกค่าเมตริกเฉพาะและเวกเตอร์การปรับแต่งที่สอดคล้องกันลงในไฟล์บันทึก:
cat( paste("result: ",v_metric," ",v_vector,sep="") , file=v_logfile, sep="n", append=T)
นี่เป็นสิ่งสำคัญ เนื่องจากจากอาร์เรย์ข้อมูลนี้ คุณจะสามารถรับข้อมูลเพิ่มเติมได้ว่าส่วนประกอบใดของเวกเตอร์การปรับแต่งที่มีผลกระทบมากกว่าหรือน้อยกว่าต่อค่าเมตริก
นั่นคือ: จะสามารถดำเนินการวิเคราะห์คุณลักษณะและความสำคัญได้
แล้วจะเกิดอะไรขึ้น?
ในรูปแบบกราฟ หากคุณเรียงลำดับการทดสอบตามลำดับเมตริกจากน้อยไปมาก รูปภาพจะเป็นดังนี้:
ข้อมูลบางอย่างที่สอดคล้องกับค่าสุดขีดของเมตริก:
ที่นี่ในภาพหน้าจอพร้อมผลลัพธ์ฉันจะชี้แจง: ค่าของเวกเตอร์การปรับแต่งจะได้รับในแง่ของโค้ดฟังก์ชันฟิตเนสไม่ใช่ในแง่ของรายการตัวเลขของพารามิเตอร์/ช่วงของค่าพารามิเตอร์ซึ่งถูกกำหนดไว้ ข้างต้นในข้อความ
ดี. มันมากหรือน้อย ~8 tps: คำถามแยกต่างหาก
ภายในกรอบการทำงานในห้องปฏิบัติการ ตัวเลขนี้ไม่สำคัญ สิ่งสำคัญคือพลวัต ค่านี้เปลี่ยนแปลงไปอย่างไร
ไดนามิกที่นี่ดี
เห็นได้ชัดว่ามีอย่างน้อยหนึ่งปัจจัยที่มีอิทธิพลอย่างมีนัยสำคัญต่อค่าของหน่วยเมตริก ga-อัลกอริทึม การเรียงลำดับผ่านเวกเตอร์ของโครโมโซม: ครอบคลุม
เมื่อพิจารณาจากการเปลี่ยนแปลงที่ค่อนข้างรุนแรงของค่าเส้นโค้ง มีอย่างน้อยหนึ่งปัจจัยที่มีอิทธิพล แม้ว่าจะน้อยกว่ามาก แต่ก็มีอิทธิพล
นี่คือที่ที่คุณต้องการ attribute-importance
การวิเคราะห์เพื่อทำความเข้าใจว่าคุณลักษณะใด (ในกรณีนี้คือส่วนประกอบของเวกเตอร์การปรับแต่ง) และคุณลักษณะเหล่านั้นมีอิทธิพลต่อค่าเมตริกมากน้อยเพียงใด
และจากข้อมูลนี้ ให้ทำความเข้าใจว่าปัจจัยใดบ้างที่ได้รับผลกระทบจากการเปลี่ยนแปลงคุณลักษณะที่สำคัญ
วิ่ง attribute-importance
เป็นไปได้ในรูปแบบต่างๆ
เพื่อจุดประสงค์เหล่านี้ ฉันชอบอัลกอริทึม randomForest
R แพ็คเกจที่มีชื่อเดียวกัน (
randomForest
เนื่องจากฉันเข้าใจงานของเขาโดยทั่วไปและแนวทางของเขาในการประเมินความสำคัญของคุณลักษณะโดยเฉพาะ ได้สร้างแบบจำลองบางอย่างของการพึ่งพาตัวแปรตอบสนองในคุณลักษณะนั้น
ในกรณีของเรา ตัวแปรการตอบสนองคือหน่วยเมตริกที่ได้รับจากฐานข้อมูลในการทดสอบโหลด: tps
;
และคุณลักษณะเป็นส่วนประกอบของเวกเตอร์การปรับแต่ง
และอื่น ๆ randomForest
ประเมินความสำคัญของแอตทริบิวต์แต่ละรุ่นด้วยตัวเลขสองตัว: %IncMSE
- การมีอยู่/ไม่มีคุณลักษณะนี้ในแบบจำลองเปลี่ยนคุณภาพ MSE ของแบบจำลองนี้อย่างไร (Mean Squared Error)
และ IncNodePurity เป็นตัวเลขที่สะท้อนให้เห็นว่าชุดข้อมูลที่มีการสังเกตสามารถแบ่งชุดข้อมูลที่มีการสังเกตได้ดีเพียงใดโดยพิจารณาจากค่าของแอตทริบิวต์นี้เพื่อให้ส่วนหนึ่งมีข้อมูลที่มีการอธิบายค่าเมตริกหนึ่งและอีกส่วนหนึ่งด้วย ค่าอื่นของเมตริก
นั่นคือ: นี่เป็นคุณลักษณะการจำแนกประเภทในระดับใด (ฉันเห็นคำอธิบายภาษารัสเซียที่ชัดเจนที่สุดใน RandomForest
รหัส R ของชาวนาคนงานสำหรับการประมวลผลชุดข้อมูลที่มีผลการทดสอบโหลด:
x=NULL
v_data_file=paste('/tmp/data1.dat',sep="")
x=read.table(v_data_file, header = TRUE, sep = ";", dec=",", quote = ""'", stringsAsFactors=FALSE)
colnames(x)=c('metric','rgsize','rgcount','lamp','cmtl','cmtw','lgbffr','lct','dbwrp','undo_retention','tprs','disk_async_io','filesystemio_options','db_block_checking','db_block_checksum')
idxTrain=sample(nrow(x),as.integer(nrow(x)*0.7))
idxNotTrain=which(! 1:nrow(x) %in% idxTrain )
TrainDS=x[idxTrain,]
ValidateDS=x[idxNotTrain,]
library(randomForest)
#mtry=as.integer( sqrt(dim(x)[2]-1) )
rf=randomForest(metric ~ ., data=TrainDS, ntree=40, mtry=3, replace=T, nodesize=2, importance=T, do.trace=10, localImp=F)
ValidateDS$predicted=predict(rf, newdata=ValidateDS[,colnames(ValidateDS)!="metric"], type="response")
sum((ValidateDS$metric-ValidateDS$predicted)^2)
rf$importance
คุณสามารถเลือกไฮเปอร์พารามิเตอร์ของอัลกอริทึมได้โดยตรงด้วยมือของคุณ และโดยมุ่งเน้นไปที่คุณภาพของแบบจำลอง ให้เลือกแบบจำลองที่ตอบสนองการคาดการณ์ในชุดข้อมูลการตรวจสอบได้แม่นยำยิ่งขึ้น
คุณสามารถเขียนฟังก์ชันบางประเภทสำหรับงานนี้ (โดยวิธีอีกครั้งโดยใช้อัลกอริธึมการปรับให้เหมาะสมบางประเภท)
คุณสามารถใช้แพ็คเกจ R caret
ไม่ใช่ประเด็นสำคัญ
ด้วยเหตุนี้ ในกรณีนี้ จึงได้ผลลัพธ์ต่อไปนี้เพื่อประเมินระดับความสำคัญของคุณลักษณะ:
ดี. ดังนั้นเราจึงสามารถเริ่มต้นการไตร่ตรองทั่วโลกได้:
- ปรากฎว่าพารามิเตอร์ที่สำคัญที่สุดภายใต้เงื่อนไขการทดสอบเหล่านี้
commit_wait
ในทางเทคนิค จะระบุโหมดการดำเนินการของการดำเนินการ io ในการเขียนข้อมูลซ้ำจากบัฟเฟอร์บันทึก subdb ไปยังกลุ่มบันทึกปัจจุบัน: ซิงโครนัสหรืออะซิงโครนัส
มูลค่าnowait
ซึ่งส่งผลให้ค่าของเมตริก tps เพิ่มขึ้นเกือบแนวตั้งหลายเท่า: นี่คือการรวมโหมด io แบบอะซิงโครนัสในกลุ่มทำซ้ำ
คำถามอีกข้อคือคุณควรทำเช่นนี้ในฐานข้อมูลอาหารหรือไม่ ในที่นี้ฉันจำกัดตัวเองเพียงแต่ระบุว่า นี่เป็นปัจจัยสำคัญ - เป็นเหตุผลที่ขนาดของบัฟเฟอร์บันทึกของ subd: กลายเป็นปัจจัยสำคัญ
ยิ่งขนาดบัฟเฟอร์บันทึกมีขนาดเล็กลง ความสามารถในการบัฟเฟอร์ก็จะยิ่งน้อยลง บ่อยครั้งบัฟเฟอร์ล้นและ/หรือไม่สามารถจัดสรรพื้นที่ว่างในนั้นสำหรับส่วนหนึ่งของข้อมูลรีดอกซ์ใหม่ได้
ซึ่งหมายความว่า: ความล่าช้าที่เกี่ยวข้องกับการจัดสรรพื้นที่ในบัฟเฟอร์บันทึกและ/หรือการเทข้อมูลซ้ำจากบัฟเฟอร์ลงในกลุ่มทำซ้ำ
แน่นอนว่าความล่าช้าเหล่านี้ควรและส่งผลกระทบต่อปริมาณงานของฐานข้อมูลสำหรับการทำธุรกรรม - พารามิเตอร์
db_block_checksum
: โดยทั่วไปแล้วมันก็ชัดเจน - การประมวลผลธุรกรรมนำไปสู่การก่อตัวของบล็อก darty ในแคชบัฟเฟอร์ของฐานข้อมูลย่อย
ซึ่งเมื่อเปิดใช้งานการตรวจสอบเช็คซัมของบล็อกข้อมูล ฐานข้อมูลจะต้องประมวลผล - คำนวณเช็คซัมเหล่านี้จากเนื้อหาของบล็อกข้อมูล ตรวจสอบกับสิ่งที่เขียนไว้ในส่วนหัวของบล็อกข้อมูล: ตรงกัน/ไม่ตรงกัน
งานดังกล่าวไม่สามารถชะลอการประมวลผลข้อมูลได้อีกครั้งดังนั้นพารามิเตอร์และกลไกที่ตั้งค่าพารามิเตอร์นี้จึงมีนัยสำคัญ
นั่นเป็นสาเหตุที่ผู้ขายเสนอค่าที่แตกต่างกันในเอกสารประกอบสำหรับพารามิเตอร์นี้ (พารามิเตอร์) และตั้งข้อสังเกตว่าใช่จะมีผลกระทบ แต่คุณสามารถเลือกค่าที่แตกต่างกันได้สูงสุดถึง "ปิด" และ ผลกระทบที่แตกต่างกัน
ข้อสรุประดับโลก
โดยทั่วไปแล้วแนวทางนี้ค่อนข้างได้ผล
เขาค่อนข้างยอมให้ตัวเองในช่วงแรกของการทดสอบโหลดของระบบบริการบางอย่าง เพื่อเลือกการกำหนดค่าที่เหมาะสมที่สุด (ระบบ) สำหรับโหลด โดยไม่เจาะลึกมากเกินไปในการตั้งค่าระบบสำหรับโหลด
แต่ไม่ได้แยกออกทั้งหมด - อย่างน้อยก็ในระดับความเข้าใจ: ต้องทราบระบบเกี่ยวกับ "ปุ่มปรับ" และช่วงการหมุนที่อนุญาตของปุ่มเหล่านี้
วิธีการนี้สามารถค้นหาการกำหนดค่าระบบที่เหมาะสมที่สุดได้อย่างรวดเร็ว
และจากผลการทดสอบ สามารถรับข้อมูลเกี่ยวกับลักษณะของความสัมพันธ์ระหว่างตัวชี้วัดประสิทธิภาพของระบบและค่าของพารามิเตอร์การตั้งค่าระบบได้
ซึ่งแน่นอนว่าควรมีส่วนทำให้เกิดความเข้าใจอย่างลึกซึ้งเกี่ยวกับระบบ การทำงานของระบบ อย่างน้อยก็ภายใต้ภาระที่กำหนด
ในทางปฏิบัติ นี่คือการแลกเปลี่ยนค่าใช้จ่ายในการทำความเข้าใจระบบที่ปรับแต่งเองกับค่าใช้จ่ายในการเตรียมการทดสอบระบบดังกล่าว
ฉันต้องการทราบแยกต่างหาก: ในแนวทางนี้ ระดับความเพียงพอของการทดสอบระบบกับสภาวะการทำงานที่จะมีในการปฏิบัติการเชิงพาณิชย์มีความสำคัญอย่างยิ่ง
ขอบคุณสำหรับความสนใจและเวลาของคุณ
ที่มา: will.com