Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla

Hei

Päätin jakaa löydöni - ajatuksen, yrityksen ja erehdyksen hedelmän.
Yleisesti ottaen: tämä ei tietenkään ole löytö - kaiken tämän olisi pitänyt tietää jo pitkään niille, jotka ovat mukana sovelletussa tilastollisessa tietojenkäsittelyssä ja minkä tahansa järjestelmän optimoinnissa, ei välttämättä erityisesti DBMS:n.
Ja: kyllä, he tietävät, he kirjoittavat mielenkiintoisia artikkeleita tutkimuksestaan, esimerkki (UPD.: kommenteissa he toivat esiin erittäin mielenkiintoisen projektin: ottertune )
Toisaalta: en näe tämän lähestymistavan laajaa mainintaa tai leviämistä Internetissä IT-asiantuntijoiden, DBA:n, keskuudessa.

Asiaan siis.

Oletetaan, että meillä on tehtävä: perustaa tietty palvelujärjestelmä palvelemaan jonkinlaista työtä.

Tästä työstä tiedetään: mitä se on, miten tämän työn laatua mitataan ja mikä on tämän laadun mittauskriteeri.

Oletetaan myös, että se on enemmän tai vähemmän tiedossa ja ymmärretty: miten tässä palvelujärjestelmässä (tai sen kanssa) tehdään työtä.

"Enemmän tai vähemmän" - tämä tarkoittaa, että on mahdollista valmistaa (tai hankkia se jostain) tietty työkalu, apuohjelma, palvelu, joka voidaan syntetisoida ja soveltaa järjestelmään riittävällä testikuormalla siihen, mikä on tuotannossa, tuotannossa työskentelyyn riittävän sopivissa olosuhteissa.

No, oletetaan, että tälle palvelujärjestelmälle tunnetaan joukko säätöparametreja, joita voidaan käyttää tämän järjestelmän konfiguroimiseen sen työn tuottavuuden kannalta.

Ja mikä on ongelma - tästä palvelujärjestelmästä ei ole tarpeeksi täydellistä ymmärrystä, jonka avulla voit määrittää asiantuntevasti tämän järjestelmän asetukset tulevaa kuormitusta varten tietyllä alustalla ja saada järjestelmän vaadittu tuottavuus.

Hyvin. Näin on lähes aina.

Mitä voit tehdä täällä?

No, ensimmäinen asia, joka tulee mieleen, on tarkastella tämän järjestelmän dokumentaatiota. Ymmärrä, mitkä ovat säätöparametrien arvojen hyväksyttävät alueet. Ja esimerkiksi käyttämällä koordinaattilaskumenetelmää, valitse arvot järjestelmäparametreille testeissä.

Nuo. antaa järjestelmälle jonkinlainen konfiguraatio tietyn arvojoukon muodossa sen konfigurointiparametreille.

Aseta siihen testikuorma käyttämällä tätä työkalu-apuohjelmaa, kuormitusgeneraattoria.
Ja katso arvoa - vastausta tai järjestelmän laadun mittaria.

Toinen ajatus voi olla johtopäätös, että tämä on hyvin pitkä aika.

Eli: jos asetusparametreja on paljon, jos niiden ajettavien arvojen alueet ovat suuria, jos jokainen yksittäinen kuormitustesti vie paljon aikaa, niin: kyllä, kaikki tämä voi kestää kohtuuttoman paljon pitkä aika.

No, tässä on mitä voit ymmärtää ja muistaa.

Voit selvittää, että palvelujärjestelmän asetusparametrien arvojoukossa on vektori joidenkin arvojen sarjana.

Jokainen tällainen vektori, muiden asioiden ollessa sama (sikäli, että tämä vektori ei vaikuta siihen), vastaa metriikan täysin tiettyä arvoa - indikaattoria järjestelmän toiminnan laadusta testikuormituksen alaisena.

Ie

Merkitään järjestelmän konfiguraatiovektoria muodossa Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avullaMissä Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla; Missä Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla — järjestelmän kokoonpanoparametrien lukumäärä, kuinka monta näitä parametreja on.

Ja tätä vastaavan mittarin arvo Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla merkitään se nimellä
Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla, niin saamme funktion: Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla

No, sitten: kaikki tulee heti minun tapauksessani: melkein unohdettu opiskeluajalta, algoritmeihin funktion ääripään etsimiseen.

Okei, mutta tässä herää organisatorinen ja sovellettu kysymys: mitä algoritmia käyttää.

  1. Siinä mielessä - jotta voit koodata vähemmän käsin.
  2. Ja jotta se toimisi, ts. löysi ääripään (jos sellainen on), no, ainakin nopeammin kuin koordinaattilasku.

Ensimmäinen kohta vihjaa, että meidän on katsottava joihinkin ympäristöihin, joissa tällaisia ​​algoritmeja on jo toteutettu ja jotka ovat jossain muodossa valmiita käytettäväksi koodissa.
No, tiedän python и cran-r

Toinen kohta tarkoittaa, että sinun on luettava itse algoritmeista, mitä ne ovat, mitkä ovat niiden vaatimukset ja niiden työn ominaisuudet.

Ja se, mitä ne antavat, voivat olla hyödyllisiä sivuvaikutuksia - tuloksia tai suoraan itse algoritmista.

Tai ne voidaan saada algoritmin tuloksista.

Paljon riippuu syöttöolosuhteista.

Jos esimerkiksi jostain syystä haluat saada tuloksen nopeammin, sinun on katsottava gradienttilaskeutumisalgoritmeihin ja valittava niistä yksi.

Tai jos aika ei ole niin tärkeä, voit esimerkiksi käyttää stokastisia optimointimenetelmiä, kuten geneettistä algoritmia.

Ehdotan harkitsemaan tämän lähestymistavan työtä, valitsemalla järjestelmän konfiguraatio geneettisen algoritmin avulla, seuraavassa niin sanotusti laboratoriotyössä.

Alkukirjain:

  1. Olkoon palvelujärjestelmänä: oracle xe 18c
  2. Anna sen palvella transaktiotoimintaa ja tavoitetta: saada alitietokannan suurin mahdollinen läpijuoksu tapahtumassa/s.
  3. Tapahtumat voivat olla hyvin erilaisia ​​tietojen kanssa työskentelyn luonteen ja työn kontekstin osalta.
    Sovitaan, että nämä ovat tapahtumia, jotka eivät käsittele suurta määrää taulukkotietoja.
    Siinä mielessä, että ne eivät tuota enempää kumoamistietoja kuin uudelleen tekeminen eivätkä käsittele suuria prosenttiosuuksia riveistä ja suurista taulukoista.

Nämä ovat tapahtumia, jotka muuttavat yhtä riviä enemmän tai vähemmän suuressa taulukossa, ja tässä taulukossa on pieni määrä indeksejä.

Tässä tilanteessa: tapahtumien käsittelyn alitietokannan tuottavuus määräytyy varauksella redox-tietokannan käsittelyn laadun mukaan.

Vastuuvapauslauseke - jos puhumme nimenomaan subdb-asetuksista.

Koska yleisessä tapauksessa SQL-istuntojen välillä voi olla esimerkiksi tapahtumalukkeja, jotka johtuvat taulukkotietojen ja/tai taulukkomallin käyttäjien työskentelystä.

Millä on tietysti masentava vaikutus tps-metriikkaan ja tämä tulee olemaan eksogeeninen tekijä suhteessa alitietokantaan: no, näin taulukkomalli suunniteltiin ja työ sen sisältämien tietojen kanssa, että tukoksia syntyy.

Siksi kokeen puhtauden vuoksi jätämme tämän tekijän pois, ja alla selitän tarkalleen kuinka.

  1. Oletetaan varmuuden vuoksi, että 100 % tietokantaan lähetetyistä SQL-käskyistä on DML-komentoja.
    Olkoon käyttäjien alitietokannan kanssa työskentelyn ominaisuudet testeissä samat.
    Nimittäin: skl-istuntojen määrä, taulukkotiedot, kuinka skl-istunnot toimivat niiden kanssa.
  2. Subd toimii FORCE LOGGING, ARCHIVELOG modit. Flashback-tietokantatila on poistettu käytöstä alatasolla.
  3. Toista lokit: sijaitsevat erillisessä tiedostojärjestelmässä, erillisellä "levyllä";
    Muu tietokannan fyysinen komponentti: toisessa, erillisessä tiedostojärjestelmässä, erillisellä "levyllä":

Lisätietoja fyysisestä laitteesta. laboratoriotietokantakomponentit

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

Alun perin näissä kuormitusolosuhteissa halusin käyttää transaktion subd SLOB-apuohjelma
Siinä on niin upea ominaisuus, lainaan kirjoittajaa:

SLOBin ytimessä on "SLOB-menetelmä". SLOB-menetelmän tarkoituksena on testata alustoja
ilman hakemuskiistaa. Ei voi ajaa maksimaalista laitteiston suorituskykyä
käyttämällä sovelluskoodia, joka on esimerkiksi sidottu sovelluksen lukituksella tai jopa
Oracle Database -lohkojen jakaminen. Aivan oikein – tietojen jakamisesta aiheutuu ylimääräisiä kustannuksia
tietolohkoissa! Mutta SLOB – oletuskäytössään – on immuuni sellaiselle kiistalle.

Tämä ilmoitus: vastaa, se on.
On kätevää säätää cl-istuntojen rinnakkaisuuden astetta, tämä on avain -t käynnistä apuohjelma runit.sh SLOBilta
DML-komentojen prosenttiosuutta säätelee aliryhmään lähetettävien tekstiviestien määrä, jokainen tekstiistunto, parametri UPDATE_PCT
Erikseen ja erittäin kätevästi: SLOB itse, ennen latausistuntoa ja sen jälkeen - valmistelee tilastopaketin tai awr-snapshots (mikä on asetettu valmisteltavaksi).

Se kuitenkin kävi ilmi SLOB ei tue SQL-istuntoja, joiden kesto on alle 30 sekuntia.
Siksi koodasin ensin oman, työläis-talonpoika versioni kuormaimesta, ja sitten se jäi toimimaan.

Haluan selventää, mitä kuormaaja tekee ja miten se tekee sen selvyyden vuoksi.
Pohjimmiltaan latauslaite näyttää tältä:

Työntekijän koodi

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

Työntekijät käynnistetään näin:

Juoksevia työntekijöitä

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 työntekijöiden pöydät valmistetaan näin:

Taulukoiden luominen

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"

Nuo. Jokaiselle työntekijälle (käytännössä: erillinen SQL-istunto tietokannassa) luodaan oma taulukko, jonka kanssa työntekijä työskentelee.

Tämä varmistaa, että työntekijäistuntojen välillä ei ole tapahtumalukituksia.
Jokainen työntekijä: tekee samaa, omalla pöydällään, pöydät ovat kaikki samanlaisia.
Kaikki työntekijät tekevät työtä saman ajan.
Lisäksi riittävän pitkään, jotta esimerkiksi lokin vaihto tapahtuisi ehdottomasti, ja useammin kuin kerran.
No, vastaavasti syntyi siihen liittyviä kustannuksia ja vaikutuksia.
Omassa tapauksessani määritin työntekijöiden työn kestoksi 8 minuuttia.

Osa statspack-raportista, joka kuvaa aliyksikön toimintaa kuormitettuna

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

Paluu laboratoriotöihin.
Muutamme laboratorion alitietokannan seuraavien parametrien arvoja muiden asioiden ollessa samat:

  1. Tietokannan lokiryhmien koko. arvoalue: [32, 1024] MB;
  2. Lehtiryhmien lukumäärä tietokannassa. arvoalue: [2,32];
  3. log_archive_max_processes arvoalue: [1,8];
  4. commit_logging kaksi arvoa ovat sallittuja: batch|immediate;
  5. commit_wait kaksi arvoa ovat sallittuja: wait|nowait;
  6. log_buffer arvoalue: [2,128] MB.
  7. log_checkpoint_timeout arvoalue: [60,1200 XNUMX] sekuntia
  8. db_writer_processes arvoalue: [1,4]
  9. undo_retention arvoalue: [30;300] sekuntia
  10. transactions_per_rollback_segment arvoalue: [1,8]
  11. disk_asynch_io kaksi arvoa ovat sallittuja: true|false;
  12. filesystemio_options seuraavat arvot ovat sallittuja: none|setall|directIO|asynch;
  13. db_block_checking seuraavat arvot ovat sallittuja: OFF|LOW|MEDIUM|FULL;
  14. db_block_checksum seuraavat arvot ovat sallittuja: OFF|TYPICAL|FULL;

Henkilö, jolla on kokemusta Oracle-tietokantojen ylläpidosta, osaa varmasti jo sanoa, mitä ja mihin arvoihin määritetyistä parametreistä ja niiden hyväksyttävistä arvoista tulisi asettaa, jotta tietokannan tuottavuus olisi suurempi työskentelyyn tietojen kanssa, jotka on osoitettu sovelluskoodi, tässä yllä.

Mutta.

Laboratoriotyön tarkoitus on osoittaa, että optimointialgoritmi itse selventää tämän meille suhteellisen nopeasti.

Meille ei jää muuta kuin tutkia dokumenttia mukautettavissa olevan järjestelmän kautta juuri sen verran, että saadaan selville, mitä parametreja on muutettava ja millä alueilla.
Ja myös: koodaa koodi, jota käytetään toimimaan valitun optimointialgoritmin mukautetun järjestelmän kanssa.

Eli nyt koodista.
Puhuin ylempänä cran-rts.: kaikki mukautetun järjestelmän käsittelyt on järjestetty R-skriptin muodossa.

Varsinainen tehtävä, analyysi, valinta metriarvon mukaan, järjestelmän tilavektorit: tämä on paketti GA (dokumentointi)
Paketti ei tässä tapauksessa ole kovin sopiva siinä mielessä, että se odottaa vektorit (kromosomit, jos paketin kannalta) määritellään numerojonoina, joissa on murto-osa.

Ja vektorini asetusparametrien arvoista: nämä ovat 14 määrää - kokonaislukuja ja merkkijonoarvoja.

Ongelma on tietysti helppo välttää antamalla tiettyjä numeroita merkkijonoarvoille.

Näin ollen loppujen lopuksi R-skriptin pääkappale näyttää tältä:

Soita 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

Täällä avun kanssa lower и upper aliohjelman attribuutteja ga oleellisesti määritetään hakuavaruuden alue, jonka sisällä suoritetaan haku sellaiselle vektorille (tai vektoreille), joille saadaan kuntofunktion maksimiarvo.

ga-alirutiini suorittaa haun, joka maksimoi kuntotoiminnon.

No, sitten käy ilmi, että tässä tapauksessa on välttämätöntä, että kuntofunktio, joka ymmärtää vektorin arvojoukona tietyille aliparametrille, vastaanottaa metriikan aliarvosta.

Toisin sanoen: kuinka monta tietyllä aliasetuksella ja tietyllä subd:n kuormituksella: subd käsittelee tapahtumia sekunnissa.

Eli avattaessa kuntotoiminnon sisällä on suoritettava seuraava monivaiheinen vaihe:

  1. Numeroiden syöttövektorin käsittely - muuntaminen alitietoparametrien arvoiksi.
  2. Yritys luoda määrätty määrä tietyn kokoisia toistamisryhmiä. Lisäksi yritys voi epäonnistua.
    Aikakauslehtiryhmät, jotka olivat jo olemassa alaosassa, jonkin verran ja jonkin verran kokeen puhtauden vuoksi - d.b. poistettu.
  3. Jos edellinen kohta onnistuu: konfigurointiparametrien arvojen määrittäminen tietokantaan (jälleen: voi olla vika)
  4. Jos edellinen vaihe on onnistunut: subd:n pysäyttäminen, subd:n käynnistäminen, jotta äskettäin määritetyt parametriarvot tulevat voimaan. (jälleen: voi olla vika)
  5. Jos edellinen vaihe onnistui: suorita kuormitustesti. saada mittareita subd:sta.
  6. Palauta subd sen alkuperäiseen tilaan, ts. poista ylimääräiset lokiryhmät, palauta alkuperäiset alitietokantaasetukset toimimaan.

Kuntotoimintokoodi

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

Että. kaikki työt: tehdään kuntotoiminnossa.

Ga-alirutiini käsittelee vektoreita, tai oikeammin kromosomeja.
Meille tärkeintä on kromosomien valinta geeneillä, joille kuntotoiminto tuottaa suuria arvoja.

Tämä on pohjimmiltaan prosessi, jossa etsitään optimaalinen kromosomijoukko käyttämällä vektoria N-ulotteisessa hakuavaruudessa.

Erittäin selkeä, yksityiskohtainen selitys, esimerkkejä R-koodista, geneettisen algoritmin työstä.

Haluaisin erikseen mainita kaksi teknistä seikkaa.

Apukutsut toiminnosta evaluate, esimerkiksi stop-start, aliparametrin arvon asettaminen, suoritetaan perustuen cran-r toimintoja system2

Jonka avulla: kutsutaan jokin bash-skripti tai komento.

Esimerkiksi:

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

Toinen piste on viiva, evaluate toimintoja, tallentamalla tietyn metriarvon ja sitä vastaavan viritysvektorin lokitiedostoon:

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

Tämä on tärkeää, koska tästä tietojoukosta on mahdollista saada lisätietoa siitä, millä viritysvektorin komponenteilla on suurempi tai vähemmän vaikutus metrian arvoon.

Eli: on mahdollista suorittaa attribuutti-importamce-analyysi.

Joten mitä voi tapahtua?

Kaaviossa, jos tilaat testit nousevassa metrijärjestyksessä, kuva on seuraava:

Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla

Joitakin tietoja, jotka vastaavat metriikan ääriarvoja:
Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla
Tässä tulosten kuvakaappauksessa selvennän: viritysvektorin arvot on annettu kuntofunktiokoodina, ei parametrien numeroluettelona / parametriarvojen alueina, joka on muotoiltu edellä tekstissä.

Hyvin. Onko paljon vai vähän, ~8 tuhatta tps: erillinen kysymys.
Laboratoriotyön puitteissa tämä luku ei ole tärkeä, tärkeä on dynamiikka, kuinka tämä arvo muuttuu.

Dynamiikka täällä on hyvä.
On selvää, että ainakin yksi tekijä vaikuttaa merkittävästi metriikan arvoon, ga-algoritmi, lajittelu kromosomivektorien välillä: katettu.
Käyrän arvojen melko voimakkaasta dynamiikasta päätellen on olemassa ainakin vielä yksi tekijä, joka, vaikkakin huomattavasti pienempi, vaikuttaa.

Tässä tarvitset sitä attribute-importance analyysi ymmärtääksesi mitkä attribuutit (hyvin, tässä tapauksessa viritysvektorin komponentit) ja kuinka paljon ne vaikuttavat metriikkaan.
Ja näiden tietojen perusteella: ymmärrä, mihin tekijöihin merkittävien ominaisuuksien muutokset vaikuttivat.

Suorittaa attribute-importance mahdollista eri tavoilla.

Näihin tarkoituksiin pidän algoritmista randomForest Samanniminen R-paketti (dokumentointi)
randomForest, kuten ymmärrän hänen työnsä yleisesti ja hänen lähestymistapansa arvioida attribuuttien tärkeyttä erityisesti, rakentaa tietyn mallin vastausmuuttujan riippuvuudesta attribuuteista.

Meidän tapauksessamme vastemuuttuja on tietokannasta kuormitustesteissä saatu mittari: tps;
Ja attribuutit ovat viritysvektorin komponentteja.

joten tässä randomForest arvioi kunkin mallin attribuutin tärkeyden kahdella numerolla: %IncMSE — kuinka tämän attribuutin läsnäolo/puuttuminen mallissa muuttaa tämän mallin MSE-laatua (Mean Squared Error);

Ja IncNodePurity on luku, joka heijastaa sitä, kuinka hyvin tämän attribuutin arvojen perusteella havaintoja sisältävä tietojoukko voidaan jakaa siten, että toisessa osassa on tietoja, joiden yksi arvo on selitetty ja toisessa mittarin toinen arvo.
No, se on: missä määrin tämä on luokitteluattribuutti (näin selkeimmän venäjänkielisen selityksen RandomForestissa täällä).

Työläis-talonpoika R-koodi datajoukon käsittelyyn kuormitustestitulosten kanssa:

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

Voit valita algoritmin hyperparametrit suoraan käsin ja mallin laatuun keskittyen valita mallin, joka täyttää tarkemmin validointitietojoukon ennusteet.
Voit kirjoittaa tähän työhön jonkinlaisen funktion (muuten, jälleen käyttämällä jonkinlaista optimointialgoritmia).

Voit käyttää R-pakettia caret, pointti ei ole tärkeä.

Tämän seurauksena tässä tapauksessa saadaan seuraava tulos määritteiden tärkeysasteen arvioimiseksi:

Tieteellinen poke-menetelmä eli tietokantakokoonpanon valitseminen vertailuarvojen ja optimointialgoritmin avulla

Hyvin. Siten voimme aloittaa globaalin pohdinnan:

  1. Osoittautuu, että näissä testausolosuhteissa merkittävin oli parametri commit_wait
    Teknisesti se määrittää suoritustilan io-toiminnolle, jossa kirjoitetaan redo-tietoja subdb-lokipuskurista nykyiseen lokiryhmään: synkroninen tai asynkroninen.
    Arvo nowait mikä johtaa lähes pystysuoraan, moninkertaiseen kasvuun tps-metriikan arvossa: tämä on asynkronisen io-tilan sisällyttäminen redo-ryhmiin.
    Erillinen kysymys on, pitäisikö sinun tehdä tämä elintarviketietokannassa. Tässä rajoitan vain toteamaan: tämä on merkittävä tekijä.
  2. On loogista, että subd:n lokipuskurin koko osoittautuu merkittäväksi tekijäksi.
    Mitä pienempi lokipuskurin koko on, sitä pienempi on sen puskurointikapasiteetti, sitä useammin se ylivuotetaan ja/tai sitä useammin se ei pysty allokoimaan vapaata aluetta osalle uutta redox-dataa.
    Tämä tarkoittaa: viiveitä, jotka liittyvät lokipuskurin tilan varaamiseen ja/tai sen uudelleenmuokkaustietojen purkamiseen uusintaryhmiin.
    Näiden viiveiden pitäisi tietysti vaikuttaa ja vaikuttavat tietokannan suoritustehoon tapahtumia varten.
  3. Parametri db_block_checksum: no, yleensä se on myös selvää - tapahtumien käsittely johtaa darty-lohkojen muodostumiseen alitietokannan puskurin välimuistiin.
    Joka, kun tietolohkojen tarkistussummien tarkistus on käytössä, tietokannan täytyy käsitellä - laskea nämä tarkistussummat tietolohkon rungosta, tarkista ne sillä, mitä on kirjoitettu tietolohkon otsikkoon: täsmää/ei täsmää.
    Tällainen työ taas ei voi muuta kuin viivyttää tietojen käsittelyä, ja vastaavasti parametri ja mekanismi, joka asettaa tämän parametrin, osoittautuvat merkittäviksi.
    Siksi toimittaja tarjoaa tämän parametrin dokumentaatiossa eri arvoja sille (parametrille) ja huomauttaa, että kyllä, sillä on vaikutusta, mutta no, voit valita erilaisia ​​arvoja aina "pois" ja "pois" asti. erilaisia ​​vaikutuksia.

No, globaali johtopäätös.

Lähestymistapa on yleisesti ottaen varsin toimiva.

Hän sallii itselleen tietyn palvelujärjestelmän kuormitustestauksen alkuvaiheessa valitakseen sen (järjestelmän) optimaalisen konfiguraation kuormitukselle, olla sukeltamatta liikaa järjestelmän kuormitusta varten asettamisen erityispiirteisiin.

Mutta se ei sulje pois sitä kokonaan - ainakaan ymmärryksen tasolla: järjestelmän on tunnettava "säätönupit" ja näiden nuppien sallitut kiertoalueet.

Lähestymistapa voi sitten löytää suhteellisen nopeasti optimaalisen järjestelmäkokoonpanon.
Ja testaustulosten perusteella on mahdollista saada tietoa järjestelmän suorituskykymittareiden ja järjestelmän asetusparametrien arvojen välisen suhteen luonteesta.

Minkä tietysti pitäisi edesauttaa tämän erittäin syvän ymmärryksen syntyä järjestelmästä, sen toiminnasta, ainakin tietyllä kuormalla.

Käytännössä tämä on räätälöidyn järjestelmän ymmärtämisestä aiheutuvien kustannusten vaihtoa järjestelmän tällaisen testauksen valmistelukustannuksiin.

Haluan huomauttaa erikseen: tässä lähestymistavassa järjestelmän testauksen riittävyys niiden käyttöolosuhteiden kanssa, jotka sillä on kaupallisessa käytössä, on ratkaisevan tärkeää.

Kiitos huomiostasi ja ajasta.

Lähde: will.com

Lisää kommentti