Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu

Haló

Rozhodl jsem se podělit se o svůj nález – plod myšlení, pokusů a omylů.
Sečteno a podtrženo: nejedná se samozřejmě o nález - to vše by mělo být známo již dávno těm, kdo se zabývají aplikovaným statistickým zpracováním dat a optimalizací jakýchkoli systémů, ne nutně konkrétně DBMS.
A: ano, vědí, píší zajímavé články o svém výzkumu, příklad (UPD.: v komentářích upozornili na velmi zajímavý projekt: vydra )
Na druhou stranu: mimochodem nevidím žádnou rozšířenou zmínku nebo šíření tohoto přístupu na internetu mezi IT specialisty, DBA.

Takže k věci.

Předpokládejme, že máme úkol: nastavit určitý systém služeb pro obsluhu nějakého druhu práce.

O této práci je známo: co to je, jak se měří kvalita této práce a jaké je kritérium pro měření této kvality.

Předpokládejme také, že je to více či méně známé a pochopené: jak přesně se práce v tomto servisním systému (nebo s ním) provádí.

„Více či méně“ - to znamená, že je možné připravit (nebo si to odněkud získat) určitý nástroj, nástroj, službu, kterou lze syntetizovat a aplikovat na systém s testovací zátěží dostatečně adekvátní tomu, co bude ve výrobě, v podmínkách dostatečně vhodných pro práci ve výrobě.

Předpokládejme, že je známa sada parametrů nastavení pro tento servisní systém, které lze použít ke konfiguraci tohoto systému z hlediska produktivity jeho práce.

A v čem je problém - není dostatečně kompletní pochopení tohoto servisního systému, takové, které vám umožní odborně nakonfigurovat nastavení tohoto systému pro budoucí zatížení na dané platformě a získat požadovanou produktivitu systému.

Studna. To je téměř vždy případ.

Co zde můžete dělat?

No, první věc, která vás napadne, je podívat se na dokumentaci k tomuto systému. Pochopte, jaké jsou přijatelné rozsahy pro hodnoty parametrů nastavení. A například pomocí metody souřadnicového sestupu vyberte hodnoty pro systémové parametry v testech.

Tito. dát systému nějaký druh konfigurace ve formě specifické sady hodnot pro jeho konfigurační parametry.

Aplikujte na něj zkušební zatížení pomocí tohoto nástroje – generátoru zatížení.
A podívejte se na hodnotu – odezvu, neboli metriku kvality systému.

Druhá myšlenka může být závěr, že se jedná o velmi dlouhou dobu.

Tedy, to jest: pokud existuje mnoho parametrů nastavení, pokud jsou rozsahy jejich spouštěných hodnot velké, pokud dokončení každého jednotlivého zátěžového testu zabere hodně času, pak: ano, to vše může trvat nepřijatelně dlouho.

No, tady je to, co můžete pochopit a zapamatovat si.

Zjistíte, že v sadě hodnot parametrů nastavení servisního systému je vektor jako posloupnost některých hodnot.

Každý takový vektor, pokud jsou ostatní věci stejné (v tom, že není tímto vektorem ovlivněn), odpovídá zcela určité hodnotě metriky - indikátoru kvality provozu systému při zkušební zátěži.

Ie

Označme vektor konfigurace systému jako Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmuKde Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu; Kde Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu — počet konfiguračních parametrů systému, kolik těchto parametrů existuje.

A tomu odpovídající hodnota metriky Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu označme to jako
Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu, pak dostaneme funkci: Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu

No, pak: všechno se okamžitě sejde, v mém případě: téměř zapomenuté z mých studentských časů, algoritmy pro hledání extrému funkce.

Dobře, ale zde vyvstává organizační a aplikovaná otázka: jaký algoritmus použít.

  1. Ve smyslu – abyste toho mohli méně kódovat ručně.
  2. A aby to fungovalo, tzn. našel extrém (pokud existuje), no, alespoň rychleji než souřadnicový sestup.

První bod naznačuje, že se musíme podívat na některá prostředí, ve kterých již byly takové algoritmy implementovány a jsou v nějaké formě připraveny pro použití v kódu.
No, já vím python и cran-r

Druhý bod znamená, že si musíte přečíst o samotných algoritmech, co jsou, jaké jsou jejich požadavky a vlastnosti jejich práce.

A to, co dávají, mohou být užitečné vedlejší efekty - výsledky, nebo přímo z algoritmu samotného.

Nebo je lze získat z výsledků algoritmu.

Hodně záleží na vstupních podmínkách.

Pokud například z nějakého důvodu potřebujete získat výsledek rychleji, musíte se podívat na algoritmy gradientního sestupu a vybrat si jeden z nich.

Nebo, pokud čas není tak důležitý, můžete například použít metody stochastické optimalizace, jako je genetický algoritmus.

Navrhuji zvážit práci tohoto přístupu, výběru konfigurace systému pomocí genetického algoritmu, v další, abych tak řekl: laboratorní práci.

Počáteční:

  1. Nechť existuje jako systém služeb: oracle xe 18c
  2. Ať slouží transakční aktivitě a cíli: získat co nejvyšší propustnost subdatabáze, v transakcích/sec.
  3. Transakce se mohou velmi lišit povahou práce s daty a kontextem práce.
    Shodněme se, že jde o transakce, které nezpracovávají velké množství tabulkových dat.
    V tom smyslu, že negenerují více dat zpět než opakovat a nezpracovávají velká procenta řádků a velkých tabulek.

Jedná se o transakce, které mění jeden řádek ve více či méně velké tabulce s malým počtem indexů v této tabulce.

V této situaci: produktivita subdatabáze pro zpracování transakcí bude s výhradou určována kvalitou zpracování redoxní databází.

Disclaimer - pokud mluvíme konkrétně o nastavení subdb.

Protože v obecném případě může docházet např. k transakčním zámkům mezi SQL relacemi, kvůli návrhu uživatelské práce s tabulkovými daty a/nebo tabulkovým modelem.

Což bude mít samozřejmě skličující vliv na metriku TPS a bude to exogenní faktor vzhledem k subdatabázi: no, takhle byl navržen tabulkový model a práce s daty v něm, že dochází k zablokování.

Pro čistotu experimentu tedy tento faktor vyloučíme a níže upřesním jak.

  1. Předpokládejme pro jistotu, že 100 % SQL příkazů odeslaných do databáze jsou DML příkazy.
    Charakteristiky uživatelské práce s poddatabází nechť jsou v testech stejné.
    Totiž: počet sezení skl, tabulkové údaje, jak s nimi sezení skl pracují.
  2. Subd pracuje v FORCE LOGGING, ARCHIVELOG mods. Režim databáze Flashback je vypnutý na úrovni subd.
  3. Redo logs: umístěné v samostatném systému souborů, na samostatném „disku“;
    Zbytek fyzické komponenty databáze: v jiném, samostatném souborovém systému, na samostatném „disku“:

Další podrobnosti o fyzickém zařízení. komponenty laboratorní databáze

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

Zpočátku jsem za těchto podmínek zatížení chtěl použít transakční subd SLOB-utilita
Má takovou úžasnou vlastnost, budu citovat autora:

Základem SLOB je „metoda SLOB“. Metoda SLOB se zaměřuje na testování platforem
bez sporu o aplikaci. Nelze dosáhnout maximálního výkonu hardwaru
pomocí kódu aplikace, který je například vázán uzamčením aplikace nebo dokonce
sdílení bloků databáze Oracle. Správně – při sdílení dat vzniká režie
v datových blocích! Ale SLOB – ve svém výchozím nasazení – je vůči takovému sporu imunní.

Toto prohlášení: odpovídá, je.
Je vhodné regulovat míru paralelismu cl relací, to je klíč -t spusťte nástroj runit.sh od SLOB
Procento DML příkazů je regulováno v počtu textových zpráv, které jsou odeslány subd, každé textové relaci, parametru UPDATE_PCT
Samostatně a velmi pohodlně: SLOB sám, před a po zátěžové relaci - připraví statspack nebo awr-snapshots (co je nastaveno k přípravě).

Ukázalo se však, že SLOB nepodporuje relace SQL s trváním kratším než 30 sekund.
Nejprve jsem si proto nakódoval vlastní, dělnicko-rolnickou verzi nakladače a pak zůstal v provozu.

Dovolte mi objasnit, co nakladač dělá a jak to dělá, pro přehlednost.
V podstatě nakladač vypadá takto:

Pracovní kód

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

Pracovníci jsou spouštěni tímto způsobem:

Běžící dělníci

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

A stoly pro pracovníky jsou připraveny takto:

Vytvoření tabulky

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"

Tito. Pro každého pracovníka (prakticky: samostatná SQL session v DB) je vytvořena samostatná tabulka, se kterou pracovník pracuje.

To zajišťuje absenci transakčních zámků mezi pracovními relacemi.
Každý pracovník: dělá totéž, s vlastním stolem jsou všechny stoly stejné.
Všichni pracovníci vykonávají práci stejně dlouho.
Navíc na dostatečně dlouhou dobu, aby např. k přepnutí logu určitě došlo, a to vícekrát.
V souladu s tím vznikly související náklady a efekty.
V mém případě jsem nastavil délku práce dělníků na 8 minut.

Část sestavy statspack popisující provoz dílčí databáze při zatížení

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

Návrat k laboratorní práci.
Za jinak stejných podmínek budeme měnit hodnoty následujících parametrů laboratorní dílčí databáze:

  1. Velikost skupin databázových protokolů. rozsah hodnot: [32, 1024] MB;
  2. Počet skupin časopisů v databázi. rozsah hodnot: [2,32];
  3. log_archive_max_processes rozsah hodnot: [1,8];
  4. commit_logging jsou povoleny dvě hodnoty: batch|immediate;
  5. commit_wait jsou povoleny dvě hodnoty: wait|nowait;
  6. log_buffer rozsah hodnot: [2,128] MB.
  7. log_checkpoint_timeout rozsah hodnot: [60,1200] sekund
  8. db_writer_processes rozsah hodnot: [1,4]
  9. undo_retention rozsah hodnot: [30;300] sekund
  10. transactions_per_rollback_segment rozsah hodnot: [1,8]
  11. disk_asynch_io jsou povoleny dvě hodnoty: true|false;
  12. filesystemio_options jsou povoleny následující hodnoty: none|setall|directIO|asynch;
  13. db_block_checking jsou povoleny následující hodnoty: OFF|LOW|MEDIUM|FULL;
  14. db_block_checksum jsou povoleny následující hodnoty: OFF|TYPICAL|FULL;

Člověk se zkušenostmi s údržbou databází Oracle již jistě dokáže říci, co a na jaké hodnoty by se mělo ze zadaných parametrů a jejich přijatelných hodnot nastavit, aby získal větší produktivitu databáze pro práci s daty, která jsou označena kód aplikace, zde výše.

Ale.

Smyslem laboratorní práce je ukázat, že samotný optimalizační algoritmus nám to poměrně rychle objasní.

Nám zbývá jen nahlédnout do dokumentu přes přizpůsobitelný systém, abychom zjistili, jaké parametry změnit a v jakých rozsazích.
A také: nakódujte kód, který bude použit pro práci s vlastním systémem zvoleného optimalizačního algoritmu.

Takže teď o kódu.
O tom jsem mluvil výše cran-r, tj.: všechny manipulace s přizpůsobeným systémem jsou organizovány ve formě R skriptu.

Vlastní úloha, analýza, výběr podle metrické hodnoty, vektory stavu systému: to je balíček GA (dokumentaci)
Balíček v tomto případě není příliš vhodný v tom smyslu, že očekává, že vektory (chromozomy, pokud jde o balík) budou specifikovány ve formě řetězců čísel se zlomkovou částí.

A můj vektor z hodnot parametrů nastavení: to je 14 veličin - celá čísla a hodnoty řetězce.

Problému lze samozřejmě snadno předejít přiřazením určitých čísel k hodnotám řetězce.

Takže nakonec hlavní část R skriptu vypadá takto:

Volejte GA::ga

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

Tady, s pomocí lower и upper atributy podprogramu ga v podstatě je specifikována oblast vyhledávacího prostoru, ve které se bude hledat takový vektor (nebo vektory), pro který bude získána maximální hodnota fitness funkce.

Podprogram ga provádí vyhledávání maximalizující funkci fitness.

No, pak se ukazuje, že v tomto případě je nutné, aby fitness funkce, chápající vektor jako soubor hodnot pro určité parametry subd, obdržela metriku z subd.

To znamená: kolik, s daným nastavením subd a daným zatížením subd: subd zpracovává transakce za sekundu.

To znamená, že při rozkládání musí být uvnitř fitness funkce proveden následující vícekrokový krok:

  1. Zpracování vstupního vektoru čísel - jeho převod na hodnoty pro parametry dílčích dat.
  2. Pokus o vytvoření daného počtu opakovaných skupin dané velikosti. Navíc může být pokus neúspěšný.
    Skupiny časopisů, které již existovaly v subd, v určitém množství a určité velikosti, pro čistotu experimentu - d.b. smazáno.
  3. Pokud je předchozí bod úspěšný: zadání hodnot konfiguračních parametrů do databáze (opět: může dojít k selhání)
  4. Pokud je předchozí krok úspěšný: zastavení subd, spuštění subd, aby se nově zadané hodnoty parametrů projevily. (opět: může být chyba)
  5. Pokud je předchozí krok úspěšný: proveďte zátěžový test. získat metriky ze subd.
  6. Vraťte subd do původního stavu, tzn. odstranit další skupiny protokolů, vrátit původní konfiguraci poddatabáze do práce.

Kód fitness funkce

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)
}

Že. veškerá práce: vykonávána ve funkci fitness.

Podprogram ga zpracovává vektory nebo přesněji chromozomy.
U kterých je pro nás nejdůležitější výběr chromozomů s geny, pro které fitness funkce produkuje velké hodnoty.

Toto je v podstatě proces hledání optimální sady chromozomů pomocí vektoru v N-rozměrném vyhledávacím prostoru.

Velmi přehledné, podrobné vysvětlení, s příklady R-kódu, práce genetického algoritmu.

Rád bych zvlášť poznamenal dva technické body.

Pomocná volání z funkce evaluate, například stop-start, nastavení hodnoty parametru subd, se provádějí na základě cran-r funkcí system2

Pomocí čehož: je volán nějaký bash skript nebo příkaz.

Například:

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)
}
}

Druhým bodem je čára, evaluate funkce s uložením konkrétní metrické hodnoty a jejího odpovídajícího vektoru ladění do souboru protokolu:

cat( paste("result: ",v_metric," ",v_vector,sep="") , file=v_logfile, sep="n", append=T)

To je důležité, protože z tohoto pole dat bude možné získat další informace o tom, která ze složek ladícího vektoru má větší či menší vliv na metrickou hodnotu.

To znamená: bude možné provádět analýzu atributů a importu.

Co se tedy může stát?

Pokud ve formě grafu objednáte testy ve vzestupném metrickém pořadí, obrázek je následující:

Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu

Některá data odpovídající extrémním hodnotám metriky:
Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu
Zde na snímku obrazovky s výsledky upřesním: hodnoty ladícího vektoru jsou uvedeny z hlediska kódu fitness funkce, nikoli z hlediska číselného seznamu parametrů/rozsahů hodnot parametrů, který byl formulován výše v textu.

Studna. Je to hodně nebo málo, ~8 tisíc tps: samostatná otázka.
V rámci laboratorní práce tento údaj není důležitý, důležitá je dynamika, jak se tato hodnota mění.

Dynamika je zde dobrá.
Je zřejmé, že alespoň jeden faktor významně ovlivňuje hodnotu metriky, ga-algoritmus, řazení přes chromozomové vektory: pokryto.
Soudě podle poměrně silné dynamiky hodnot křivky je zde ještě minimálně jeden faktor, který, i když je výrazně menší, má vliv.

Tady to potřebujete attribute-importance analýzu, abyste pochopili, jaké atributy (tedy v tomto případě složky ladícího vektoru) a jak moc ovlivňují metrickou hodnotu.
A z těchto informací: pochopit, jaké faktory byly ovlivněny změnami významných atributů.

běh attribute-importance možné různými způsoby.

Pro tyto účely se mi líbí algoritmus randomForest R balíček se stejným názvem (dokumentaci)
randomForest, jak jeho práci rozumím obecně a jeho přístupu k posuzování důležitosti atributů konkrétně, buduje určitý model závislosti proměnné odezvy na atributech.

V našem případě je proměnná odezvy metrika získaná z databáze v zátěžových testech: tps;
A atributy jsou komponenty ladícího vektoru.

Takže tady randomForest vyhodnotí důležitost každého atributu modelu dvěma čísly: %IncMSE — jak přítomnost/nepřítomnost tohoto atributu v modelu mění kvalitu MSE tohoto modelu (střední kvadratická chyba);

A IncNodePurity je číslo, které odráží, jak dobře lze na základě hodnot tohoto atributu rozdělit datovou sadu s pozorováními, takže v jedné části jsou data s jednou vysvětlovanou hodnotou metriky a ve druhé s jinou hodnotu metriky.
Tedy, do jaké míry je to klasifikační atribut (nejjasnější ruskojazyčné vysvětlení jsem viděl na RandomForest zde).

Dělnicko-rolnický R-kód pro zpracování datové sady s výsledky zátěžových testů:

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

Můžete přímo vybrat hyperparametry algoritmu rukama a se zaměřením na kvalitu modelu vybrat model, který přesněji splňuje predikce na ověřovací datové sadě.
Pro tuto práci můžete napsat nějakou funkci (mimochodem, opět pomocí nějakého optimalizačního algoritmu).

Můžete použít balíček R caret, pointa není důležitá.

Výsledkem je, že v tomto případě je k posouzení stupně důležitosti atributů získán následující výsledek:

Metoda vědeckého poke aneb jak vybrat konfiguraci databáze pomocí benchmarků a optimalizačního algoritmu

Studna. Můžeme tedy začít globální reflexi:

  1. Ukazuje se, že nejvýznamnější byl za těchto testovacích podmínek parametr commit_wait
    Technicky specifikuje režim provádění operace io zápisu redo dat z vyrovnávací paměti protokolu subdb do aktuální skupiny protokolů: synchronní nebo asynchronní.
    Hodnota nowait což má za následek téměř vertikální, mnohonásobné zvýšení hodnoty metriky tps: jedná se o zařazení asynchronního režimu io do skupin redo.
    Samostatnou otázkou je, zda byste to měli udělat v databázi potravin. Zde se omezím pouze na konstatování: toto je významný faktor.
  2. Je logické, že velikost log bufferu subd: se ukazuje jako významný faktor.
    Čím menší je velikost log bufferu, tím menší je jeho vyrovnávací kapacita, tím častěji dochází k přetečení a/nebo nemožnosti alokovat v něm volnou oblast pro část nových redoxních dat.
    To znamená: zpoždění spojená s alokací místa ve vyrovnávací paměti protokolu a/nebo ukládáním redo dat z ní do redo skupin.
    Tato zpoždění by samozřejmě měla ovlivnit propustnost databáze pro transakce a také to ovlivňuje.
  3. Parametr db_block_checksum: No, obecně je to jasné - zpracování transakcí vede k vytvoření darty bloků ve vyrovnávací paměti poddatabáze.
    Což, když je povolena kontrola kontrolních součtů databloků, musí databáze zpracovat - vypočítat tyto kontrolní součty z těla databloku, zkontrolovat je s tím, co je napsáno v hlavičce databloku: shoduje se/neodpovídá.
    Taková práce opět nemůže zpozdit zpracování dat, a proto se parametr a mechanismus, který tento parametr nastavuje, ukazují jako významné.
    To je důvod, proč dodavatel nabízí v dokumentaci pro tento parametr různé hodnoty pro tento parametr (parametr) a poznamenává, že ano, bude to mít vliv, ale můžete si vybrat různé hodnoty, až do „vypnuto“ a různé dopady.

No, globální závěr.

Tento přístup se obecně ukazuje jako docela funkční.

Docela si dovoluje v raných fázích zátěžového testování určitého obslužného systému vybrat jeho (systémovou) optimální konfiguraci pro zátěž, nezabývat se příliš specifiky nastavení systému pro zátěž.

Ale nevylučuje to úplně - alespoň na úrovni porozumění: systém musí být obeznámen s „regulačními knoflíky“ a přípustnými rozsahy otáčení těchto knoflíků.

Přístup pak dokáže poměrně rychle najít optimální konfiguraci systému.
A na základě výsledků testování je možné získat informace o povaze vztahu mezi metrikami výkonu systému a hodnotami parametrů nastavení systému.

Což by samozřejmě mělo přispět ke vzniku tohoto velmi hlubokého pochopení systému, jeho fungování, alespoň při dané zátěži.

V praxi se jedná o výměnu nákladů na pochopení přizpůsobeného systému za náklady na přípravu takového testování systému.

Samostatně bych chtěl poznamenat: v tomto přístupu je kriticky důležitý stupeň přiměřenosti testování systému k provozním podmínkám, které bude mít v komerčním provozu.

Děkuji za pozornost a čas.

Zdroj: www.habr.com

Přidat komentář