Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil

Tere

Otsustasin jagada oma leidu – mõtte, katse-eksituse vilja.
Üldiselt: see pole muidugi leid - see kõik oleks pidanud olema juba ammu teada neile, kes tegelevad rakendusliku statistilise andmetöötluse ja mis tahes süsteemide optimeerimisega, mitte tingimata konkreetselt DBMS-iga.
Ja: jah, nad teavad, nad kirjutavad oma uurimistööst huvitavaid artikleid, näide (UPD.: kommentaarides tõid nad välja väga huvitava projekti: Ottertune )
Teisest küljest: ma ei näe selle lähenemisviisi laialdast mainimist ega levitamist Internetis IT-spetsialistide, DBA, seas.

Niisiis, asja juurde.

Oletame, et meil on ülesanne: seadistada teatud teenindussüsteem mingi töö teenindamiseks.

Selle töö kohta on teada: mis see on, kuidas selle töö kvaliteeti mõõdetakse ja mis on selle kvaliteedi mõõtmise kriteerium.

Oletame ka, et enam-vähem teatakse ja mõistetakse: kuidas täpselt selles teenindussüsteemis (või sellega) tööd tehakse.

"Enam-vähem" - see tähendab, et on võimalik ette valmistada (või kuskilt hankida) teatud tööriist, utiliit, teenus, mida saab sünteesida ja süsteemi rakendada katsekoormusega, mis on piisavalt adekvaatne tootmises olevale, tootmises töötamiseks piisavalt piisavates tingimustes.

Noh, oletame, et on teada selle teenindussüsteemi reguleerimisparameetrid, mida saab kasutada selle süsteemi konfigureerimiseks selle töö produktiivsuse seisukohast.

Ja mis on probleem - sellest teenindussüsteemist pole piisavalt täielikku arusaamist, mis võimaldab teil asjatundlikult konfigureerida selle süsteemi sätteid tulevaseks koormuseks antud platvormil ja saavutada süsteemi vajalik tootlikkus.

Noh. See on peaaegu alati nii.

Mida sa siin teha saad?

Noh, esimene asi, mis meelde tuleb, on vaadata selle süsteemi dokumentatsiooni. Saate aru, millised on reguleerimisparameetrite väärtuste vastuvõetavad vahemikud. Ja näiteks koordinaatide laskumise meetodi abil valige testides süsteemi parameetrite väärtused.

Need. anda süsteemile mingisugune konfiguratsioon selle konfiguratsiooniparameetrite konkreetse väärtuste komplekti kujul.

Rakendage sellele testkoormus, kasutades just seda tööriista-utiliiti, koormusgeneraatorit.
Ja vaadake väärtust – vastust või süsteemi kvaliteedi mõõdikut.

Teine mõte võib olla järeldus, et see on väga pikk aeg.

Noh, see tähendab: kui häälestusparameetreid on palju, kui nende väärtuste vahemikud on suured, kui iga üksiku koormustesti sooritamine võtab palju aega, siis: jah, see kõik võib võtta lubamatult kaua aega.

Noh, siin on see, mida saate mõista ja meelde jätta.

Saate teada, et teenindussüsteemi sätete parameetrite väärtuste komplektis on mõne väärtuse jadana vektor.

Iga selline vektor, kui muud tegurid on võrdsed (sellest, et see vektor seda ei mõjuta), vastab meetrika täiesti kindlale väärtusele - süsteemi töö kvaliteedi näitajale testkoormusel.

St

Tähistame süsteemi konfiguratsioonivektorit kui Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abilKus Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil; Kus Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil — süsteemi konfiguratsiooniparameetrite arv, nende parameetrite arv.

Ja sellele vastava mõõdiku väärtus Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil tähistame seda kui
Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil, siis saame funktsiooni: Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil

Noh, siis: kõik taandub minu puhul kohe sellele: minu tudengiajast peaaegu unustatud algoritmidele funktsiooni ekstreemumi otsimiseks.

Olgu, aga siin tekib organisatsiooniline ja rakenduslik küsimus: millist algoritmi kasutada.

  1. Selles mõttes – et saaks vähem käsitsi kodeerida.
  2. Ja et see toimiks, st. leidis ekstreemumi (kui see on olemas), noh, vähemalt kiiremini kui koordinaatide laskumine.

Esimene punkt vihjab, et me peame vaatama mõnda keskkonda, kus sellised algoritmid on juba rakendatud ja on mingil kujul koodis kasutamiseks valmis.
No ma tean python и cran-r

Teine punkt tähendab, et peate lugema algoritmide endi kohta, millised need on, millised on nende nõuded ja nende töö omadused.

Ja see, mida need annavad, võivad olla kasulikud kõrvalmõjud – tulemused või otse algoritmist endast.

Või saab need algoritmi tulemustest.

Palju sõltub sisendtingimustest.

Näiteks kui teil on mingil põhjusel vaja tulemust kiiremini saada, siis peate vaatama gradiendi laskumisalgoritmide poole ja valima neist ühe.

Või kui aeg pole nii oluline, võite kasutada näiteks stohhastilisi optimeerimise meetodeid, näiteks geneetilist algoritmi.

Teen ettepaneku kaaluda selle lähenemisviisi tööd, valides süsteemi konfiguratsiooni, kasutades geneetilist algoritmi, järgmises, nii-öelda laboritöös.

Originaal:

  1. Olgu teenindussüsteemina: oracle xe 18c
  2. Las see teenib tehingutegevust ja eesmärki: saada alamandmebaasi võimalikult suur läbilaskevõime, tehingutes/s.
  3. Tehingud võivad andmetega töötamise olemuse ja töö konteksti poolest olla väga erinevad.
    Lepime kokku, et need on tehingud, mis ei töötle suurt hulka tabeliandmeid.
    Selles mõttes, et nad ei genereeri rohkem tagasivõtmisandmeid kui teevad uuesti ega töötle suuri protsente ridu ja suuri tabeleid.

Need on tehingud, mis muudavad ühte rida enam-vähem suures tabelis, kusjuures sellel tabelis on väike arv indekseid.

Sellises olukorras: tehingute töötlemise alamandmebaasi tootlikkuse määrab reservatsiooniga redoksandmebaasi töötlemise kvaliteet.

Kohustustest loobumine – kui me räägime konkreetselt alam-DB sätetest.

Sest üldjuhul võib SQL-i seansside vahel esineda näiteks tehingulukke, mis on tingitud tabeliandmete ja/või tabelimudeliga kasutaja töö ülesehitusest.

Mis muidugi avaldab TPS-i mõõdikule pärssivat mõju ja see on alamandmebaasi suhtes eksogeenne tegur: noh, nii loodi tabelmudel ja töö selles sisalduvate andmetega, et tekivad ummistused.

Seetõttu jätame katse puhtuse huvides selle teguri välja ja allpool selgitan täpselt, kuidas.

  1. Oletame kindluse mõttes, et 100% andmebaasi edastatavatest SQL-käskudest on DML-käsud.
    Olgu kasutajate alamandmebaasiga töö omadused testides samad.
    Nimelt: skl-seansside arv, tabeliandmed, kuidas skl-seansid nendega töötavad.
  2. Subd töötab FORCE LOGGING, ARCHIVELOG modifikatsioonid. Flashback-andmebaasi režiim on alamtasemel välja lülitatud.
  3. Logid uuesti: asuvad eraldi failisüsteemis, eraldi “kettal”;
    Ülejäänud andmebaasi füüsiline komponent: teises, eraldi failisüsteemis, eraldi "kettal":

Lisateave füüsilise seadme kohta. laboratoorsete andmebaaside komponendid

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

Esialgu tahtsin nendel koormustingimustel kasutada tehingu subd SLOB-utiliit
Sellel on nii imeline omadus, tsiteerin autorit:

SLOBi keskmes on "SLOB-meetod". SLOB-meetodi eesmärk on testida platvorme
ilma taotluse esitamiseta. Riistvara maksimaalset jõudlust ei saa juhtida
kasutades rakenduse koodi, mis on näiteks seotud rakenduse lukustamisega või isegi
Oracle'i andmebaasiplokkide jagamine. Täpselt nii – andmete jagamisega kaasneb lisakulu
andmeplokkides! Kuid SLOB – vaikimisi juurutamisel – on sellise vaidluse suhtes immuunne.

See deklaratsioon: vastab, on.
cl-seansside paralleelsuse astet on mugav reguleerida, see on võti -t käivitage utiliit runit.sh firmalt SLOB
DML-käskude protsent on reguleeritud subd-le saadetavate tekstisõnumite arvu, iga tekstiseansi, parameetri järgi. UPDATE_PCT
Eraldi ja väga mugavalt: SLOB ise, enne ja pärast laadimisseanssi – koostab statspacki ehk awr-snapshots (mis on ette valmistatud).

Siiski selgus, et SLOB ei toeta SQL-i seansse, mille kestus on alla 30 sekundi.
Seetõttu kodeerisin esmalt oma, töölis-talupoja versiooni laadurist ja siis jäi see tööle.

Selguse huvides lubage mul selgitada, mida ja kuidas laadur teeb.
Põhimõtteliselt näeb laadur välja selline:

Töötaja kood

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

Töötajad käivitatakse järgmiselt:

Jooksvad töötajad

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

Ja töötajate lauad valmistatakse järgmiselt:

Tabelite koostamine

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"

Need. Iga töötaja jaoks (praktiliselt: eraldi SQL seanss DB-s) luuakse eraldi tabel, millega töötaja töötab.

See tagab tehingulukkude puudumise töötajate seansside vahel.
Iga töötaja: teeb sama asja, oma lauaga, lauad on kõik ühesugused.
Kõik töötajad teevad tööd sama kaua.
Pealegi piisavalt pikaks ajaks, et näiteks logivahetus kindlasti toimuks ja rohkem kui korra.
Noh, vastavalt tekkisid sellega seotud kulud ja mõjud.
Minu puhul konfigureerisin töötajate töö kestuseks 8 minutit.

Tükk statspacki aruandest, mis kirjeldab alamüksuse tööd koormuse all

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

Naasmine laboritöö juurde.
Kui muud asjaolud on võrdsed, muudame labori alamandmebaasi järgmiste parameetrite väärtusi:

  1. Andmebaasi logirühmade suurus. väärtusvahemik: [32, 1024] MB;
  2. Ajakirjarühmade arv andmebaasis. väärtusvahemik: [2,32];
  3. log_archive_max_processes väärtusvahemik: [1,8];
  4. commit_logging kaks väärtust on lubatud: batch|immediate;
  5. commit_wait kaks väärtust on lubatud: wait|nowait;
  6. log_buffer väärtusvahemik: [2,128] MB.
  7. log_checkpoint_timeout väärtusvahemik: [60,1200 XNUMX] sekundit
  8. db_writer_processes väärtusvahemik: [1,4]
  9. undo_retention väärtusvahemik: [30;300] sekundit
  10. transactions_per_rollback_segment väärtusvahemik: [1,8]
  11. disk_asynch_io kaks väärtust on lubatud: true|false;
  12. filesystemio_options järgmised väärtused on lubatud: none|setall|directIO|asynch;
  13. db_block_checking järgmised väärtused on lubatud: OFF|LOW|MEDIUM|FULL;
  14. db_block_checksum järgmised väärtused on lubatud: OFF|TYPICAL|FULL;

Oracle'i andmebaaside haldamise kogemusega inimene oskab kindlasti juba praegu öelda, milliseid ja milliseid väärtusi tuleks määratud parameetritest ja nende vastuvõetavatest väärtustest seada, et saavutada andmebaasi suurem tootlikkus tööks andmetega, mida näidatakse. rakenduse kood, siin ülal.

Kuid.

Laboritöö mõte on näidata, et optimeerimisalgoritm ise teeb selle meile suhteliselt kiiresti selgeks.

Meie jaoks ei jää muud üle, kui vaadata dokumenti läbi kohandatava süsteemi, et teada saada, milliseid parameetreid muuta ja millistes vahemikes.
Ja ka: kodeerige kood, mida kasutatakse valitud optimeerimisalgoritmi kohandatud süsteemiga töötamiseks.

Niisiis, nüüd koodist.
Eespool rääkisin sellest cran-rst: kõik kohandatud süsteemiga manipulatsioonid on korraldatud R-skripti kujul.

Tegelik ülesanne, analüüs, valik meetrilise väärtuse järgi, süsteemi olekuvektorid: see on pakett GA (dokumentatsiooni)
Antud juhul pakett ei ole eriti sobiv selles mõttes, et eeldab vektorite (kromosoomide, kui paketi mõttes) täpsustamist murdosaga arvujadade kujul.

Ja minu vektor seadistusparameetrite väärtustest: need on 14 kogust - täisarvud ja stringi väärtused.

Probleemi on muidugi lihtne vältida, määrates stringiväärtustele teatud numbrid.

Seega näeb R-skripti põhiosa lõpuks välja selline:

Helista 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

Siin, abiga lower и upper alamprogrammi atribuudid ga sisuliselt määratakse otsinguruumi ala, mille sees otsitakse sellist vektorit (või vektoreid), mille jaoks saadakse sobivusfunktsiooni maksimaalne väärtus.

Alamprogramm ga teostab otsingut, mis maksimeerib sobivuse funktsiooni.

Noh, siis selgub, et sel juhul on vajalik, et sobivusfunktsioon, mõistes vektorit kui alamd teatud parameetrite väärtuste kogumit, saaks alamd-st mõõdiku.

See tähendab: kui palju, antud alam-seadistuse ja alam-alamkoormuse antud koormusega: alamd töötleb tehinguid sekundis.

See tähendab, et lahti voltimisel tuleb fitnessfunktsiooni sees läbi viia järgmine mitmesamm:

  1. Numbrite sisendvektori töötlemine - selle teisendamine alamandmete parameetrite väärtusteks.
  2. Katse luua etteantud arv kindla suurusega ümbertegemise gruppe. Pealegi võib katse ebaõnnestuda.
    Ajakirjade rühmad, mis olid juba alamdis, mingis koguses ja mingis suuruses, eksperimendi puhtuse huvides - d.b. kustutatud.
  3. Kui eelmine punkt õnnestus: konfiguratsiooniparameetrite väärtuste määramine andmebaasi (jällegi: võib esineda tõrge)
  4. Kui eelmine samm on edukas: peatada alam, käivitada alam, et äsja määratud parameetri väärtused jõustuksid. (jälle: võib olla tõrge)
  5. Kui eelmine samm õnnestus: tehke koormustest. hankige mõõdikud alamdist.
  6. Taastage subd algsesse olekusse, st. kustutage täiendavad logirühmad, tagastage algse alamandmebaasi konfiguratsioon tööle.

Fitness funktsiooni kood

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

See. kõik tööd: tehakse fitnessi funktsioonis.

Ga-alamprogramm töötleb vektoreid või õigemini kromosoome.
Milles on meie jaoks kõige olulisem kromosoomide valik geenidega, mille jaoks fitnessi funktsioon toodab suuri väärtusi.

Sisuliselt on see protsess, mille käigus otsitakse optimaalset kromosoomide komplekti, kasutades vektorit N-mõõtmelises otsinguruumis.

Väga selge, detailne selgitus, R-koodi näidetega, geneetilise algoritmi töö.

Tahaksin eraldi välja tuua kaks tehnilist punkti.

Abikõned funktsioonist evaluate, näiteks stop-start, alamparameetri väärtuse määramine, tehakse lähtuvalt cran-r funktsioonid system2

Mille abil: kutsutakse välja mingi bash skript või käsk.

Näiteks:

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

Teine punkt on joon, evaluate funktsioonid, salvestades konkreetse mõõdiku väärtuse ja sellele vastava häälestusvektori logifaili:

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

See on oluline, kuna sellest andmemassiivist on võimalik saada lisateavet selle kohta, milline häälestusvektori komponentidest mõjutab meetrika väärtust suuremal või vähemal määral.

See tähendab: atribuudi-tähtsuse analüüsi on võimalik läbi viia.

Mis siis juhtuda võib?

Graafiku kujul, kui tellite testid kasvavas mõõdiku järjekorras, on pilt järgmine:

Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil

Mõned andmed, mis vastavad mõõdiku äärmuslikele väärtustele:
Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil
Siin, tulemustega ekraanipildil, selgitan: häälestusvektori väärtused on antud sobivusfunktsiooni koodi järgi, mitte sõnastatud parameetrite/parameetrite väärtuste vahemike numbriloendis. eespool tekstis.

Noh. Kas seda on palju või vähe, ~8 tuhat tps: omaette küsimus.
Laboritöö raames pole see näitaja oluline, oluline on dünaamika, kuidas see väärtus muutub.

Dünaamika on siin hea.
On ilmne, et vähemalt üks tegur mõjutab oluliselt mõõdiku väärtust, ga-algoritm, sorteerides kromosoomivektorite vahel: kaetud.
Kõverate väärtuste üsna jõulise dünaamika järgi otsustades on veel vähemalt üks tegur, mis, kuigi oluliselt väiksem, omab mõju.

Siin on seda vaja attribute-importance analüüsi, et mõista, millised atribuudid (hästi, antud juhul häälestusvektori komponendid) ja kui palju need mõõdiku väärtust mõjutavad.
Ja selle teabe põhjal: mõista, milliseid tegureid mõjutasid oluliste atribuutide muutused.

jooks attribute-importance võimalik erinevatel viisidel.

Nendel eesmärkidel mulle algoritm meeldib randomForest Samanimeline R-pakett (dokumentatsiooni)
randomForest, nagu ma mõistan tema tööd üldiselt ja lähenemist atribuutide olulisuse hindamisele, ehitab teatud mudeli vastuse muutuja sõltuvusest atribuutidest.

Meie puhul on vastuse muutujaks koormustestides andmebaasist saadud mõõdik: tps;
Ja atribuudid on häälestusvektori komponendid.

Nii et randomForest hindab iga mudeli atribuudi tähtsust kahe numbriga: %IncMSE — kuidas selle atribuudi olemasolu/puudumine mudelis muudab selle mudeli MSE kvaliteeti (keskmine ruudu viga);

Ja IncNodePurity on arv, mis peegeldab seda, kui hästi saab selle atribuudi väärtuste põhjal jagada vaatlustega andmekogumit nii, et ühes osas on andmed ühe seletatava mõõdiku väärtusega ja teises osas mõõdiku teine ​​väärtus.
Noh, see on: mil määral on see klassifitseeriv atribuut (ma nägin RandomForestis kõige selgemat venekeelset selgitust siin).

Töötaja-talupoja R-kood andmestiku töötlemiseks koos koormustestide tulemustega:

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

Algoritmi hüperparameetrid saate otse oma kätega valida ja mudeli kvaliteedile keskendudes valida mudeli, mis täidab täpsemalt valideerimisandmestiku ennustusi.
Selle töö jaoks saab kirjutada mingisuguse funktsiooni (muide, jällegi, kasutades mingit optimeerimisalgoritmi).

Võite kasutada R-paketti caret, mitte point pole oluline.

Selle tulemusel saadakse atribuutide tähtsuse määramiseks antud juhul järgmine tulemus:

Teaduslik poke meetod ehk kuidas valida andmebaasi konfiguratsiooni võrdlusaluste ja optimeerimisalgoritmi abil

Noh. Seega võime alustada globaalset refleksiooni:

  1. Selgub, et nendes katsetingimustes oli kõige olulisem parameeter commit_wait
    Tehniliselt määrab see alamdb-logipuhvrist praegusesse logirühma redo-andmete kirjutamise io-operatsiooni täitmisrežiimi: sünkroonne või asünkroonne.
    Väärtus nowait mille tulemuseks on tps-mõõdiku väärtuse peaaegu vertikaalne mitmekordne suurenemine: see on asünkroonse io-režiimi kaasamine ümbertegemise rühmadesse.
    Omaette küsimus on, kas seda peaks tegema toiduainete andmebaasis või mitte. Piirdun siinkohal vaid tõdemusega: see on oluline tegur.
  2. On loogiline, et subd: logipuhvri suurus osutub oluliseks teguriks.
    Mida väiksem on logipuhvri suurus, seda väiksem on selle puhverdusvõime, seda sagedamini täitub see üle ja/või ei ole võimalik eraldada selles vaba ala uute redoksandmete osa jaoks.
    See tähendab: viivitused, mis on seotud logipuhvris ruumi eraldamisega ja/või sealt taastegemise andmete taastegemise rühmadesse koondamisega.
    Need viivitused peaksid muidugi mõjutama ja mõjutavad ka tehingute andmebaasi läbilaskevõimet.
  3. Parameeter db_block_checksum: noh, üldiselt on see selge - tehingute töötlemine viib alamandmebaasi puhvervahemällu darty-plokkide moodustumiseni.
    Mida, kui andmeplokkide kontrollsummade kontrollimine on lubatud, peab andmebaas töötlema - arvutama need kontrollsummad andmeploki kehast välja, kontrollima andmeploki päises kirjutatuga: sobib/ei ühti.
    Selline töö ei saa jällegi muud kui andmetöötlust viivitada ja sellest tulenevalt osutuvad selle parameetri määrav parameeter ja mehhanism oluliseks.
    Sellepärast pakub müüja selle parameetri dokumentatsioonis selle (parameetri) jaoks erinevaid väärtusi ja märgib, et jah, sellel on mõju, kuid noh, saate valida erinevaid väärtusi, kuni "väljas" ja erinevad mõjud.

Noh, globaalne järeldus.

Üldiselt osutub lähenemisviis üsna toimivaks.

Ta lubab endale üsnagi teatud teenindussüsteemi koormustestimise algstaadiumis, et valida selle (süsteemi) koormuse jaoks optimaalne konfiguratsioon, mitte liiga palju süveneda koormuse jaoks süsteemi seadistamise eripäradesse.

Kuid see ei välista seda täielikult - vähemalt mõistmise tasemel: süsteem peab olema teada "reguleerimisnuppude" ja nende nuppude lubatud pöörlemisvahemike kohta.

See lähenemisviis võib seejärel suhteliselt kiiresti leida optimaalse süsteemikonfiguratsiooni.
Ja testimise tulemuste põhjal on võimalik saada teavet süsteemi jõudlusmõõdikute ja süsteemiseadete parameetrite väärtuste vahelise seose olemuse kohta.

Mis muidugi peaks aitama kaasa selle väga sügava arusaamise tekkimisele süsteemist, selle toimimisest, vähemalt antud koormuse juures.

Praktikas on see kohandatud süsteemi mõistmise kulude vahetamine süsteemi sellise testimise ettevalmistamise kulude vastu.

Tahaksin eraldi märkida: selle lähenemisviisi puhul on süsteemi testimise adekvaatsuse aste kommertskasutuses olevate töötingimustega kriitilise tähtsusega.

Tänan teid tähelepanu ja aja eest.

Allikas: www.habr.com

Lisa kommentaar