Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği

Merhaba

Düşüncenin, deneme yanılmanın meyvesi olan buluşumu paylaşmaya karar verdim.
Genel olarak: bu elbette bir bulgu değil - tüm bunların, uygulamalı istatistiksel veri işleme ve herhangi bir sistemin optimizasyonu ile ilgilenenler için, özellikle DBMS değil, uzun zamandır bilinmesi gerekirdi.
Ve: evet biliyorlar, araştırmalarıyla ilgili ilginç makaleler yazıyorlar, örnek (GÜNCELLEME: Yorumlarda çok ilginç bir projeye dikkat çektiler: su samuru )
Öte yandan: BT uzmanları ve DBA arasında internette bu yaklaşımın yaygın bir şekilde bahsedildiğini veya yayıldığını görmüyorum.

Yani asıl noktaya.

Bir görevimiz olduğunu varsayalım: bir tür işe hizmet vermek için belirli bir hizmet sistemi kurmak.

Bu iş hakkında biliniyor: Ne olduğu, bu işin kalitesinin nasıl ölçüldüğü ve bu kaliteyi ölçmenin kriterinin ne olduğu.

Ayrıca az çok bilindiğini ve anlaşıldığını da varsayalım: Bu hizmet sisteminde (veya bu sistemle birlikte) işin tam olarak nasıl yapıldığı.

“Az çok ya da az” - bu, sentezlenebilecek ve sisteme uygulanabilecek belirli bir aracı, yardımcı programı, hizmeti üretimde olacak kadar yeterli bir test yüküyle hazırlamanın (veya bir yerden almanın) mümkün olduğu anlamına gelir, üretimde çalışmak için yeterince yeterli koşullarda.

Peki, bu hizmet sistemi için, bu sistemi işinin verimliliği açısından yapılandırmak için kullanılabilecek bir dizi ayar parametresinin bilindiğini varsayalım.

Ve sorun nedir - bu sistemin ayarlarını belirli bir platformda gelecekteki yük için ustalıkla yapılandırmanıza ve sistemin gerekli üretkenliğini elde etmenize olanak tanıyan bu hizmet sistemi hakkında yeterince eksiksiz bir anlayış yok.

Kuyu. Bu neredeyse her zaman böyledir.

Burada ne yapabilirsin?

Akla gelen ilk şey bu sistemin belgelerine bakmaktır. Ayar parametrelerinin değerleri için kabul edilebilir aralıkların ne olduğunu anlayın. Ve örneğin, koordinat iniş yöntemini kullanarak testlerde sistem parametreleri için değerleri seçin.

Onlar. sisteme, konfigürasyon parametreleri için belirli bir değerler kümesi biçiminde bir tür konfigürasyon verin.

Bu araç-faydalı yük oluşturucuyu kullanarak ona bir test yükü uygulayın.
Ve değere, tepkiye veya sistemin kalitesinin bir ölçüsüne bakın.

İkinci düşünce ise bunun çok uzun bir süre olduğu sonucu olabilir.

Yani: çok fazla ayar parametresi varsa, çalıştırılan değerlerinin aralıkları büyükse, her bir yük testinin tamamlanması çok zaman alıyorsa, o zaman: evet, tüm bunlar kabul edilemez derecede zaman alabilir uzun zaman.

İşte anlayabileceğiniz ve hatırlayabileceğiniz şeyler.

Servis sistemi ayarları parametrelerinin değer kümesinde, bazı değerlerin dizisi olarak bir vektör bulunduğunu öğrenebilirsiniz.

Bu vektörlerin her biri, diğer şeyler eşit olmak üzere (bu vektörden etkilenmediği için), bir test yükü altında sistemin çalışma kalitesinin bir göstergesi olan metriğin tamamen kesin bir değerine karşılık gelir.

Ie

Sistem konfigürasyon vektörünü şu şekilde gösterelim: Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceğiNerede Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği; Nerede Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği — sistem konfigürasyon parametrelerinin sayısı, bu parametrelerden kaç tane olduğu.

Ve buna karşılık gelen metriğin değeri Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği olarak belirtelim
Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceğisonra bir fonksiyon elde ederiz: Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği

O halde, benim durumumda her şey hemen şu noktaya geliyor: Öğrenci günlerimden beri neredeyse unutulmuş olan, bir fonksiyonun ekstremumunu aramaya yönelik algoritmalar.

Tamam, ama burada organizasyonel ve uygulamalı bir soru ortaya çıkıyor: hangi algoritmanın kullanılacağı.

  1. Bu anlamda - daha az elle kod yazabilmeniz için.
  2. Ve işe yaraması için, yani. ekstremumu buldum (eğer varsa), en azından koordinat inişinden daha hızlı.

İlk nokta, bu tür algoritmaların halihazırda uygulanmış olduğu ve bir şekilde kodda kullanıma hazır olduğu bazı ortamlara bakmamız gerektiğini ima ediyor.
Biliyorum python и cran-r

İkinci nokta, algoritmaların kendisini, ne olduklarını, gereksinimlerinin neler olduğunu ve çalışmalarının özelliklerini okumanız gerektiği anlamına gelir.

Ve verdikleri şey yararlı yan etkiler olabilir - sonuçlar veya doğrudan algoritmanın kendisinden.

Veya algoritmanın sonuçlarından elde edilebilirler.

Çoğu şey giriş koşullarına bağlıdır.

Örneğin, herhangi bir nedenle daha hızlı sonuç almanız gerekiyorsa, gradyan iniş algoritmalarına bakmanız ve bunlardan birini seçmeniz gerekir.

Veya zaman o kadar önemli değilse, örneğin genetik algoritma gibi stokastik optimizasyon yöntemlerini kullanabilirsiniz.

Bu yaklaşımın çalışmasını, sistem konfigürasyonunu seçerek, genetik bir algoritma kullanarak, tabiri caizse laboratuvar çalışması olarak düşünmeyi öneriyorum.

Temel:

  1. Bir hizmet sistemi olarak şöyle olsun: oracle xe 18c
  2. İşlemsel aktiviteye ve amaca hizmet etmesine izin verin: işlem/sn cinsinden alt veritabanında mümkün olan en yüksek verimi elde etmek.
  3. İşlemler, verilerle çalışmanın doğası ve işin bağlamı açısından çok farklı olabilir.
    Bunların büyük miktarda tablosal veriyi işlemeyen işlemler olduğunu kabul edelim.
    Bu anlamda, yinelemeden daha fazla geri alma verisi üretmezler ve büyük yüzdelerdeki satırları ve büyük tabloları işlemezler.

Bunlar, az sayıda indeks bulunan, az çok büyük bir tabloda bir satırı değiştiren işlemlerdir.

Bu durumda: İşlemlerin işlenmesi için alt veritabanının üretkenliği, bir çekinceyle, redoks veritabanı tarafından yapılan işlemenin kalitesine göre belirlenecektir.

Sorumluluk reddi beyanı - özellikle alt db ayarları hakkında konuşursak.

Çünkü genel durumda, tablo verileri ve/veya tablo modeli ile kullanıcı çalışmasının tasarlanması nedeniyle, örneğin SQL oturumları arasında işlem kilitlenmeleri olabilir.

Elbette bu, TPS metriği üzerinde olumsuz bir etkiye sahip olacak ve bu, alt veritabanına göre dışsal bir faktör olacaktır: tablo modeli bu şekilde tasarlandı ve içindeki verilerle çalışma, tıkanmaların meydana gelmesine neden oluyor.

Bu nedenle deneyin saflığı için bu faktörü hariç tutacağız ve aşağıda tam olarak nasıl olduğunu açıklayacağım.

  1. Kesinlik açısından veritabanına gönderilen SQL komutlarının %100'ünün DML komutları olduğunu varsayalım.
    Testlerde alt veritabanı ile çalışan kullanıcının özellikleri aynı olsun.
    Yani: skl oturumlarının sayısı, tablo verileri, skl oturumlarının bunlarla nasıl çalıştığı.
  2. Subd'da çalışıyor FORCE LOGGING, ARCHIVELOG modlar. Flashback-veritabanı modu alt düzeyde kapatılır.
  3. Yineleme günlükleri: ayrı bir dosya sisteminde, ayrı bir “disk”te bulunur;
    Veritabanının fiziksel bileşeninin geri kalanı: başka, ayrı bir dosya sisteminde, ayrı bir "disk"te:

Fiziksel cihaz hakkında daha fazla ayrıntı. laboratuvar veritabanı bileşenleri

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

Başlangıçta bu yük koşulları altında subd işlemini kullanmak istedim. SLOB-yardımcı programı
O kadar harika bir özelliği var ki, yazardan alıntı yapacağım:

SLOB'un kalbinde "SLOB yöntemi" yer alır. SLOB Yöntemi platformları test etmeyi amaçlamaktadır
uygulama çekişmesi olmadan. Maksimum donanım performansını elde edemezsiniz
örneğin uygulama kilitlemeyle bağlanan uygulama kodunu kullanarak veya hatta
Oracle Veritabanı bloklarını paylaşma. Doğru; veri paylaşımında ek yük var
veri bloklarında! Ancak SLOB (varsayılan dağıtımında) bu tür çekişmelere karşı bağışıktır.

Bu beyan: karşılık gelir, öyledir.
CL oturumlarının paralellik derecesini düzenlemek uygundur, anahtar budur -t yardımcı programı başlat runit.sh SLOB'dan
DML komutlarının yüzdesi, alt dizine gönderilen metin mesajlarının sayısına, her bir metin oturumuna, parametreye göre düzenlenir. UPDATE_PCT
Ayrı olarak ve çok uygun bir şekilde: SLOB yükleme oturumundan önce ve sonra kendisi bir istatistik paketi veya awr anlık görüntüleri (hazırlanmak üzere ayarlanmış olan) hazırlar.

Ancak ortaya çıktı ki SLOB 30 saniyeden kısa süren SQL oturumlarını desteklemez.
Bu nedenle, yükleyicinin önce kendi işçi-köylü versiyonunu kodladım ve sonra çalışır durumda kaldı.

Açıklık sağlamak için yükleyicinin ne yaptığını ve nasıl yaptığını açıklayayım.
Temel olarak yükleyici şuna benzer:

İşçi kodu

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

İşçiler şu şekilde başlatılır:

Çalışan işçiler

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

İşçilere yönelik masalar ise şöyle hazırlanıyor:

Tablo oluşturma

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"

Onlar. Her çalışan için (pratik olarak: Veritabanında ayrı bir SQL oturumu), çalışanın birlikte çalıştığı ayrı bir tablo oluşturulur.

Bu, çalışan oturumları arasında işlem kilitlerinin bulunmamasını sağlar.
Her işçi: kendi masasıyla aynı şeyi yapıyor, masaların hepsi aynı.
Tüm işçiler aynı süre boyunca iş yaparlar.
Üstelik, örneğin bir günlük değişiminin kesinlikle gerçekleşeceği kadar uzun bir süre ve birden fazla kez.
Dolayısıyla buna bağlı maliyetler ve etkiler ortaya çıktı.
Benim durumumda işçilerin çalışma süresini 8 dakika olarak ayarladım.

Yük altında bir alt veritabanının çalışmasını açıklayan bir istatistik paketi raporu parçası

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

Laboratuvar çalışmalarına geri dönüyoruz.
Diğer şeylerin eşit olması durumunda, laboratuvar alt veri tabanındaki aşağıdaki parametrelerin değerlerini değiştireceğiz:

  1. Veritabanı günlük gruplarının boyutu. değer aralığı: [32, 1024] MB;
  2. Veritabanındaki dergi gruplarının sayısı. değer aralığı: [2,32];
  3. log_archive_max_processes değer aralığı: [1,8];
  4. commit_logging iki değere izin verilir: batch|immediate;
  5. commit_wait iki değere izin verilir: wait|nowait;
  6. log_buffer değer aralığı: [2,128] MB.
  7. log_checkpoint_timeout değer aralığı: [60,1200] saniye
  8. db_writer_processes değer aralığı: [1,4]
  9. undo_retention değer aralığı: [30;300] saniye
  10. transactions_per_rollback_segment değer aralığı: [1,8]
  11. disk_asynch_io iki değere izin verilir: true|false;
  12. filesystemio_options aşağıdaki değerlere izin verilir: none|setall|directIO|asynch;
  13. db_block_checking aşağıdaki değerlere izin verilir: OFF|LOW|MEDIUM|FULL;
  14. db_block_checksum aşağıdaki değerlere izin verilir: OFF|TYPICAL|FULL;

Oracle veritabanlarının bakımı konusunda deneyimi olan bir kişi, belirtilen verilerle çalışmak için veritabanının daha fazla üretkenliğini elde etmek amacıyla, belirtilen parametrelerden ve kabul edilebilir değerlerden neyin ve hangi değerlerin ayarlanması gerektiğini kesinlikle söyleyebilir. uygulama kodu burada, yukarıda.

Ama.

Laboratuvar çalışmasının amacı, optimizasyon algoritmasının kendisinin bunu bizim için nispeten hızlı bir şekilde açıklığa kavuşturacağını göstermektir.

Bizim için geriye kalan tek şey, özelleştirilebilir sistem aracılığıyla, hangi parametrelerin hangi aralıklarda değiştirileceğini bulmak için belgeye bakmaktır.
Ve ayrıca: seçilen optimizasyon algoritmasının özel sistemiyle çalışmak için kullanılacak kodu kodlayın.

Şimdi kod hakkında.
yukarıda bahsetmiştim cran-r, yani: özelleştirilmiş sistemdeki tüm manipülasyonlar bir R betiği biçiminde düzenlenir.

Gerçek görev, analiz, metrik değere göre seçim, sistem durumu vektörleri: bu bir pakettir GA (документация)
Bu durumda paket, vektörlerin (paket açısından kromozomların) kesirli kısmı olan sayı dizileri biçiminde belirtilmesini beklemesi anlamında pek uygun değildir.

Ve benim vektörüm, ayar parametrelerinin değerlerinden: bunlar 14 miktardır - tamsayılar ve dize değerleri.

Tabii ki, dize değerlerine bazı belirli sayılar atanarak sorun kolayca önlenir.

Böylece, sonunda R betiğinin ana parçası şuna benzer:

GA::ga'yı arayın

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

Burada, yardımla lower и upper altprogram özellikleri ga esas olarak, uygunluk fonksiyonunun maksimum değerinin elde edileceği böyle bir vektör (veya vektörler) için bir aramanın gerçekleştirileceği arama alanının bir alanı belirtilir.

Ga alt yordamı uygunluk fonksiyonunu maksimuma çıkaran bir arama gerçekleştirir.

Öyleyse, bu durumda, vektörü, altd'nin belirli parametreleri için bir değerler kümesi olarak anlayan uygunluk fonksiyonunun, altd'den bir metrik alması gerektiği ortaya çıktı.

Yani: belirli bir alt dizin kurulumu ve alt dizin üzerindeki belirli bir yük ile kaç tane: alt dizin saniyede işlemleri işler.

Yani, açılırken uygunluk fonksiyonu içinde aşağıdaki çoklu adımın gerçekleştirilmesi gerekir:

  1. Sayıların giriş vektörünün işlenmesi - alt veri parametrelerinin değerlerine dönüştürülmesi.
  2. Belirli bir boyutta belirli sayıda yineleme grubu oluşturma girişimi. Üstelik girişim başarısız da olabilir.
    Deneyin saflığı için alt bölümde zaten mevcut olan, belirli miktarda ve boyuttaki dergi grupları - d.b. silindi.
  3. Önceki nokta başarılıysa: konfigürasyon parametrelerinin değerlerinin veritabanına belirtilmesi (yine: bir arıza olabilir)
  4. Önceki adım başarılı olursa: yeni belirtilen parametre değerlerinin etkili olması için subd'yi durdurmak, subd'yi başlatmak. (tekrar: bir aksaklık olabilir)
  5. Önceki adım başarılı olursa: bir yük testi yapın. subd'dan metrikleri alın.
  6. Subd'yi orijinal durumuna döndürün, yani. ek günlük gruplarını silin, orijinal alt veritabanı yapılandırmasını çalışmaya döndürün.

Fitness fonksiyon kodu

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

O. tüm işler: uygunluk fonksiyonunda gerçekleştirilir.

Ga-altyordamı vektörleri veya daha doğrusu kromozomları işler.
Burada bizim için en önemli olan, uygunluk fonksiyonunun büyük değerler ürettiği genlere sahip kromozomların seçimidir.

Bu, özünde, N boyutlu bir arama uzayında bir vektör kullanarak en uygun kromozom setini arama sürecidir.

Çok net, detaylı açıklamaGenetik algoritmanın çalışması olan R kodu örnekleriyle.

İki teknik noktayı ayrı ayrı belirtmek isterim.

Fonksiyondan yardımcı çağrılar evaluateörneğin stop-start, subd parametresinin değerinin ayarlanması, buna göre gerçekleştirilir. cran-r işlevler system2

Bunun yardımıyla: bazı bash komut dosyaları veya komutları çağrılır.

Örneğin:

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

İkinci nokta ise çizgidir. evaluate Belirli bir metrik değeri ve buna karşılık gelen ayarlama vektörünü bir günlük dosyasına kaydeden işlevler:

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

Bu önemlidir, çünkü bu veri dizisinden, ayarlama vektörünün hangi bileşenlerinin metrik değer üzerinde daha fazla veya daha az etkiye sahip olduğu hakkında ek bilgi elde etmek mümkün olacaktır.

Yani nitelik-önem analizi yapmak mümkün olacaktır.

Peki ne olabilir?

Grafik formunda testleri artan metrik sıraya göre sıralarsanız resim aşağıdaki gibidir:

Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği

Metriğin uç değerlerine karşılık gelen bazı veriler:
Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği
Burada, sonuçların yer aldığı ekran görüntüsünde açıklığa kavuşturacağım: ayarlama vektörünün değerleri, formüle edilen parametre sayısı listesi/parametre değerleri aralıkları cinsinden değil, uygunluk fonksiyon kodu cinsinden verilmiştir. metinde yukarıda.

Kuyu. Çok mu az mı, ~8 bin tps: ayrı bir soru.
Laboratuvar çalışması çerçevesinde bu rakam önemli değil, önemli olan dinamikler, bu değerin nasıl değiştiği.

Buradaki dinamikler iyi.
En az bir faktörün, kromozom vektörleri arasında sıralama yapan ga-algoritması olan metriğin değerini önemli ölçüde etkilediği açıktır: kapsanan.
Eğri değerlerinin oldukça güçlü dinamiklerine bakılırsa, önemli ölçüde daha küçük olmasına rağmen etkisi olan en az bir faktör daha var.

İhtiyacınız olan yer burası attribute-importance Hangi özelliklerin (yani bu durumda ayarlama vektörünün bileşenlerinin) ve bunların metrik değeri ne kadar etkilediğini anlamak için analiz.
Ve bu bilgilerden yola çıkarak: Önemli niteliklerdeki değişikliklerden hangi faktörlerin etkilendiğini anlayın.

Çalıştırmak attribute-importance farklı şekillerde mümkündür.

Bu amaçlar için algoritmayı seviyorum randomForest Aynı isimli R paketi (документация)
randomForestGenel olarak çalışmasını ve özel olarak niteliklerin önemini değerlendirmeye yönelik yaklaşımını anladığım kadarıyla, yanıt değişkeninin niteliklere bağımlılığına ilişkin belirli bir model oluşturuyor.

Bizim durumumuzda yanıt değişkeni, yük testlerinde veritabanından elde edilen bir metriktir: tps;
Ve nitelikler ayarlama vektörünün bileşenleridir.

Ve böylece randomForest her model özelliğinin önemini iki sayıyla değerlendirir: %IncMSE — bir modelde bu özelliğin varlığı/yokluğu, bu modelin MSE kalitesini nasıl değiştirir (Ortalama Karesel Hata);

Ve IncNodePurity, bu özelliğin değerlerine dayanarak, gözlemleri içeren bir veri kümesinin ne kadar iyi bölünebileceğini yansıtan bir sayıdır, böylece bir bölümde metriğin bir değeri açıklanan veriler bulunurken diğerinde açıklanır. metriğin başka bir değeri.
Yani: bu ne ölçüde bir sınıflandırma özelliğidir (en açık, Rusça açıklamayı RandomForest'ta gördüm) burada).

Yük testlerinin sonuçlarını içeren bir veri kümesini işlemek için işçi-köylü R kodu:

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

Algoritmanın hiper parametrelerini doğrudan ellerinizle seçebilir ve modelin kalitesine odaklanarak doğrulama veri kümesindeki tahminleri daha doğru şekilde karşılayan bir model seçebilirsiniz.
Bu iş için bir tür fonksiyon yazabilirsiniz (bu arada, yine bir tür optimizasyon algoritması kullanarak).

R paketini kullanabilirsiniz caret, önemli olan nokta değil.

Sonuç olarak bu durumda niteliklerin önem derecesini değerlendirmek için aşağıdaki sonuç elde edilir:

Bilimsel dürtme yöntemi veya kıyaslamalar ve bir optimizasyon algoritması kullanılarak bir veritabanı yapılandırmasının nasıl seçileceği

Kuyu. Böylece küresel yansımaya başlayabiliriz:

  1. Bu test koşulları altında en önemli parametrenin parametre olduğu ortaya çıktı. commit_wait
    Teknik olarak, yineleme verilerinin subdb günlük arabelleğinden geçerli günlük grubuna yazılmasına ilişkin io işleminin yürütme modunu belirtir: eşzamanlı veya eşzamansız.
    Değer nowait bu da tps metriğinin değerinde neredeyse dikey, çoklu bir artışa neden olur: bu, eşzamansız io modunun yineleme gruplarına dahil edilmesidir.
    Ayrı bir soru, bunu bir gıda veritabanında yapıp yapmamanız gerektiğidir. Burada kendimi sadece şunu belirtmekle sınırlandırıyorum: Bu önemli bir faktör.
  2. Subd:'in günlük arabelleğinin boyutunun önemli bir faktör olduğu ortaya çıkması mantıklıdır.
    Günlük arabelleğinin boyutu ne kadar küçük olursa, ara belleğe alma kapasitesi o kadar az olur, taşma sıklığı artar ve/veya yeni redoks verilerinin bir kısmı için içinde boş bir alan tahsis edilememesi.
    Bu şu anlama gelir: günlük arabelleğinde yer ayırma ve/veya yineleme verilerinin yineleme gruplarına boşaltılmasıyla ilişkili gecikmeler.
    Bu gecikmeler elbette işlemler için veritabanının verimini etkilemelidir ve etkilemelidir.
  3. Parametre db_block_checksum: ayrıca, genel olarak açıktır - işlem işleme, alt veritabanının arabellek önbelleğinde dart bloklarının oluşumuna yol açar.
    Bu, veri bloklarının sağlama toplamlarını kontrol ederken, veritabanının işlemesi gerekir - bu sağlama toplamlarını veri bloğunun gövdesinden hesaplamak, bunları veri bloğu başlığında yazılanlarla kontrol etmek: eşleşiyor/eşleşmiyor.
    Bu tür çalışmalar yine veri işlemeyi geciktirmekten başka bir şey yapamaz ve buna göre parametre ve bu parametreyi ayarlayan mekanizma önemli hale gelir.
    Satıcının bu parametrenin belgelerinde bunun için farklı değerler (parametre) sunmasının nedeni budur ve evet, bir etki olacağını not eder, ancak "kapalı" ya kadar farklı değerler seçebilirsiniz ve farklı etkiler.

Peki, küresel bir sonuç.

Yaklaşımın genel olarak oldukça işe yaradığı ortaya çıktı.

Belirli bir servis sisteminin yük testinin ilk aşamalarında, yük için sistemin (sistem) en uygun konfigürasyonunu seçmek ve sistemi yük için kurmanın ayrıntılarına çok fazla dalmamak için kendisine oldukça izin verir.

Ancak bunu tamamen dışlamaz - en azından anlayış düzeyinde: sistemin "ayar düğmeleri" ve bu düğmelerin izin verilen dönüş aralıkları hakkında bilinmesi gerekir.

Yaklaşım daha sonra nispeten hızlı bir şekilde optimum sistem konfigürasyonunu bulabilir.
Ve test sonuçlarına dayanarak, sistem performans metrikleri ile sistem ayar parametrelerinin değerleri arasındaki ilişkinin niteliği hakkında bilgi edinmek mümkündür.

Elbette bu, sistemin en azından belirli bir yük altında işleyişine ilişkin bu çok derin anlayışın ortaya çıkmasına katkıda bulunmalıdır.

Uygulamada bu, özelleştirilmiş sistemi anlama maliyetlerinin, sistemin bu tür testlerini hazırlama maliyetleriyle değiştirilmesidir.

Ayrıca belirtmek isterim ki, bu yaklaşımda sistem testinin ticari işletmede sahip olacağı çalışma koşullarına uygunluk derecesi kritik önem taşımaktadır.

İlginiz ve zamanınız için teşekkür ederiz.

Kaynak: habr.com

Yorum ekle