Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa

Xin chào

Tôi quyết định chia sẻ phát hiện của mình - thành quả của sự suy nghĩ, thử nghiệm và sai sót.
Nhìn chung: tất nhiên đây không phải là một phát hiện - tất cả những điều này đáng lẽ phải được biết từ lâu đối với những người tham gia vào việc xử lý và tối ưu hóa dữ liệu thống kê ứng dụng của bất kỳ hệ thống nào, không nhất thiết phải cụ thể là DBMS.
Và: vâng, họ biết, họ viết những bài báo thú vị về nghiên cứu của mình, Ví dụ (CẬP NHẬT: trong phần bình luận họ đã chỉ ra một dự án rất thú vị: rái cá )
Mặt khác: trực tiếp tôi không thấy bất kỳ đề cập hoặc phổ biến rộng rãi nào về phương pháp này trên Internet giữa các chuyên gia CNTT, DBA.

Vì vậy, đến mức.

Giả sử rằng chúng ta có một nhiệm vụ: thiết lập một hệ thống dịch vụ nhất định để phục vụ một số loại công việc.

Người ta đã biết về tác phẩm này: nó là gì, chất lượng của tác phẩm này được đo lường như thế nào và tiêu chí nào để đo lường chất lượng này.

Cũng giả sử rằng nó ít nhiều được biết và hiểu: chính xác cách thức thực hiện công việc trong (hoặc với) hệ thống dịch vụ này.

“Nhiều hay ít” - điều này có nghĩa là có thể chuẩn bị (hoặc lấy nó từ đâu đó) một công cụ, tiện ích, dịch vụ nhất định có thể được tổng hợp và áp dụng vào hệ thống với tải thử nghiệm đủ phù hợp với những gì sẽ được đưa vào sản xuất, có đủ điều kiện để làm việc trong sản xuất.

Chà, giả sử rằng đã biết một tập hợp các tham số điều chỉnh cho hệ thống dịch vụ này, có thể được sử dụng để định cấu hình hệ thống này về mặt năng suất làm việc của nó.

Và vấn đề là gì - không có sự hiểu biết đầy đủ về hệ thống dịch vụ này, hệ thống cho phép bạn định cấu hình một cách thành thạo các cài đặt của hệ thống này để tải trong tương lai trên một nền tảng nhất định và đạt được năng suất cần thiết của hệ thống.

Tốt. Điều này hầu như luôn luôn như vậy.

Bạn có thể làm gì ở đây?

Chà, điều đầu tiên bạn nghĩ đến là xem tài liệu về hệ thống này. Hiểu phạm vi có thể chấp nhận được đối với các giá trị của tham số điều chỉnh. Và, ví dụ, bằng cách sử dụng phương pháp gốc tọa độ, hãy chọn các giá trị cho các tham số hệ thống trong các thử nghiệm.

Những thứ kia. cung cấp cho hệ thống một số loại cấu hình, dưới dạng một bộ giá trị cụ thể cho các tham số cấu hình của nó.

Áp dụng tải thử nghiệm cho nó bằng cách sử dụng chính công cụ tạo tải tiện ích này.
Và hãy nhìn vào giá trị - phản hồi hoặc thước đo chất lượng của hệ thống.

Ý nghĩ thứ hai có thể là kết luận rằng đây là một thời gian rất dài.

Chà, đó là: nếu có nhiều tham số cài đặt, nếu phạm vi giá trị của chúng đang được chạy lớn, nếu mỗi lần kiểm tra tải riêng lẻ mất nhiều thời gian để hoàn thành, thì: vâng, tất cả điều này có thể mất một khoảng thời gian không thể chấp nhận được thời gian dài.

Vâng, đây là những gì bạn có thể hiểu và ghi nhớ.

Bạn có thể phát hiện ra rằng trong tập hợp các giá trị của tham số cài đặt hệ thống dịch vụ có một vectơ, dưới dạng một chuỗi của một số giá trị.

Mỗi vectơ như vậy, những thứ khác bằng nhau (trong đó nó không bị ảnh hưởng bởi vectơ này), tương ứng với một giá trị hoàn toàn xác định của số liệu - một chỉ báo về chất lượng hoạt động của hệ thống trong tải thử nghiệm.

Tức là

Chúng ta hãy biểu thị vectơ cấu hình hệ thống là Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóaĐâu Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa; Ở đâu Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa - số lượng tham số cấu hình hệ thống, có bao nhiêu tham số trong số này.

Và giá trị của số liệu tương ứng với điều này Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa hãy biểu thị nó là
Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa, thì chúng ta nhận được một hàm: Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa

Vậy thì: trong trường hợp của tôi, mọi thứ ngay lập tức liên quan đến: các thuật toán tìm kiếm cực trị của một hàm gần như bị lãng quên từ thời còn là sinh viên của tôi.

Được rồi, nhưng ở đây nảy sinh một câu hỏi mang tính tổ chức và ứng dụng: nên sử dụng thuật toán nào.

  1. Theo nghĩa nào đó - để bạn có thể viết mã ít hơn bằng tay.
  2. Và để nó hoạt động, tức là đã tìm thấy cực trị (nếu có), à, ít nhất là nhanh hơn so với việc giảm tọa độ.

Điểm đầu tiên gợi ý rằng chúng ta cần hướng tới một số môi trường trong đó các thuật toán như vậy đã được triển khai và ở một dạng nào đó đã sẵn sàng để sử dụng trong mã.
À tôi biết python и cran-r

Điểm thứ hai có nghĩa là bạn cần đọc về bản thân các thuật toán, chúng là gì, yêu cầu của chúng là gì và các tính năng công việc của chúng.

Và những gì họ đưa ra có thể là những tác dụng phụ hữu ích - kết quả, hoặc trực tiếp từ chính thuật toán.

Hoặc chúng có thể thu được từ kết quả của thuật toán.

Rất nhiều phụ thuộc vào các điều kiện đầu vào.

Ví dụ: nếu vì lý do nào đó, bạn cần nhận được kết quả nhanh hơn, thì bạn cần xem xét các thuật toán giảm độ dốc và chọn một trong số chúng.

Hoặc, nếu thời gian không quá quan trọng, chẳng hạn, bạn có thể sử dụng các phương pháp tối ưu hóa ngẫu nhiên, chẳng hạn như thuật toán di truyền.

Tôi đề xuất xem xét công việc của phương pháp này, chọn cấu hình hệ thống, sử dụng thuật toán di truyền, có thể nói là tiếp theo: công việc trong phòng thí nghiệm.

Ban đầu:

  1. Hãy để có, như một hệ thống dịch vụ: oracle xe 18c
  2. Hãy để nó phục vụ hoạt động giao dịch và mục tiêu: đạt được thông lượng cao nhất có thể của cơ sở dữ liệu con, tính bằng giao dịch/giây.
  3. Các giao dịch có thể rất khác nhau về bản chất làm việc với dữ liệu và bối cảnh công việc.
    Hãy đồng ý rằng đây là những giao dịch không xử lý một lượng lớn dữ liệu dạng bảng.
    Theo nghĩa là chúng không tạo ra nhiều dữ liệu hoàn tác hơn dữ liệu làm lại và không xử lý phần lớn các hàng và bảng lớn.

Đây là các giao dịch thay đổi một hàng trong một bảng lớn ít nhiều, với một số lượng nhỏ chỉ mục trên bảng này.

Trong tình huống này: năng suất của cơ sở dữ liệu con để xử lý các giao dịch sẽ được xác định bởi chất lượng xử lý của cơ sở dữ liệu oxy hóa khử.

Tuyên bố từ chối trách nhiệm - nếu chúng ta nói cụ thể về cài đặt subdb.

Bởi vì, trong trường hợp chung, chẳng hạn, có thể có các khóa giao dịch giữa các phiên SQL, do thiết kế của người dùng làm việc với dữ liệu dạng bảng và/hoặc mô hình dạng bảng.

Tất nhiên, điều này sẽ có tác động làm giảm chỉ số TPS và đây sẽ là một yếu tố ngoại sinh, liên quan đến cơ sở dữ liệu con: à, đây là cách mô hình dạng bảng được thiết kế và hoạt động với dữ liệu trong đó gây ra tắc nghẽn.

Do đó, để đảm bảo tính thuần khiết của thí nghiệm, chúng tôi sẽ loại trừ yếu tố này và dưới đây tôi sẽ làm rõ chính xác như thế nào.

  1. Để rõ ràng, chúng ta hãy giả sử rằng 100% lệnh SQL được gửi tới cơ sở dữ liệu là các lệnh DML.
    Hãy để các đặc điểm của người dùng làm việc với cơ sở dữ liệu con giống nhau trong các thử nghiệm.
    Cụ thể: số phiên skl, dữ liệu dạng bảng, cách phiên skl hoạt động với chúng.
  2. Subd hoạt động ở FORCE LOGGING, ARCHIVELOG mod. Chế độ cơ sở dữ liệu hồi tưởng bị tắt ở cấp độ phụ.
  3. Làm lại nhật ký: nằm trong một hệ thống tệp riêng biệt, trên một “đĩa” riêng biệt;
    Phần còn lại của thành phần vật lý của cơ sở dữ liệu: trong một hệ thống tệp riêng biệt khác, trên một “đĩa” riêng biệt:

Thêm chi tiết về thiết bị vật lý. thành phần cơ sở dữ liệu phòng thí nghiệm

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

Ban đầu, trong các điều kiện tải này, tôi muốn sử dụng subd giao dịch Tiện ích SLOB
Nó có một tính năng tuyệt vời như vậy, tôi sẽ trích dẫn tác giả:

Trọng tâm của SLOB là “phương pháp SLOB”. Phương pháp SLOB nhằm mục đích thử nghiệm các nền tảng
không có tranh chấp ứng dụng. Người ta không thể thúc đẩy hiệu suất phần cứng tối đa
sử dụng mã ứng dụng, ví dụ như bị ràng buộc bởi khóa ứng dụng hoặc thậm chí
chia sẻ các khối cơ sở dữ liệu Oracle. Đúng vậy—có chi phí khi chia sẻ dữ liệu
trong khối dữ liệu! Nhưng SLOB—trong cách triển khai mặc định—không bị ảnh hưởng bởi sự tranh chấp như vậy.

Tuyên bố này: tương ứng, nó là.
Thật thuận tiện để điều chỉnh mức độ song song của các phiên cl, đây là chìa khóa -t khởi chạy tiện ích runit.sh từ SLOB
Tỷ lệ phần trăm lệnh DML được quy định, về số lượng tin nhắn văn bản được gửi đến subd, mỗi phiên văn bản, tham số UPDATE_PCT
Riêng biệt và rất thuận tiện: SLOB chính nó, trước và sau phiên tải - chuẩn bị một gói thống kê hoặc ảnh chụp nhanh awr (những gì được thiết lập để chuẩn bị).

Tuy nhiên, hóa ra là SLOB không hỗ trợ các phiên SQL có thời lượng dưới 30 giây.
Vì vậy, trước tiên tôi đã mã hóa phiên bản trình tải công nhân-nông dân của riêng mình và sau đó nó vẫn hoạt động.

Hãy để tôi làm rõ trình tải làm gì và nó hoạt động như thế nào cho rõ ràng.
Về cơ bản, trình tải trông như thế này:

Mã công nhân

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

Công nhân được đưa ra theo cách này:

Công nhân chạy bộ

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

Và bàn dành cho công nhân được chuẩn bị như thế này:

Tạo bảng

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"

Những thứ kia. Đối với mỗi nhân viên (thực tế là: một phiên SQL riêng biệt trong DB), một bảng riêng biệt được tạo để nhân viên làm việc.

Điều này đảm bảo không có khóa giao dịch giữa các phiên làm việc.
Mỗi công nhân: làm giống nhau, có bàn riêng, các bàn đều giống nhau.
Tất cả công nhân đều thực hiện công việc trong một khoảng thời gian như nhau.
Hơn nữa, trong một thời gian đủ dài để chẳng hạn, việc chuyển đổi nhật ký chắc chắn sẽ xảy ra và hơn một lần.
Vâng, theo đó, chi phí và tác động liên quan đã phát sinh.
Trong trường hợp của tôi, tôi đã định cấu hình thời lượng làm việc của công nhân là 8 phút.

Một phần của báo cáo gói thống kê mô tả hoạt động của subd đang tải

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

Trở lại công việc trong phòng thí nghiệm.
Chúng tôi sẽ, những thứ khác không đổi, thay đổi giá trị của các tham số sau của cơ sở dữ liệu con phòng thí nghiệm:

  1. Kích thước của các nhóm nhật ký cơ sở dữ liệu. phạm vi giá trị: [32, 1024] MB;
  2. Số lượng nhóm tạp chí trong cơ sở dữ liệu. phạm vi giá trị: [2,32];
  3. log_archive_max_processes phạm vi giá trị: [1,8];
  4. commit_logging hai giá trị được phép: batch|immediate;
  5. commit_wait hai giá trị được phép: wait|nowait;
  6. log_buffer phạm vi giá trị: [2,128] MB.
  7. log_checkpoint_timeout phạm vi giá trị: [60,1200] giây
  8. db_writer_processes phạm vi giá trị: [1,4]
  9. undo_retention phạm vi giá trị: [30;300] giây
  10. transactions_per_rollback_segment phạm vi giá trị: [1,8]
  11. disk_asynch_io hai giá trị được phép: true|false;
  12. filesystemio_options các giá trị sau được cho phép: none|setall|directIO|asynch;
  13. db_block_checking các giá trị sau được cho phép: OFF|LOW|MEDIUM|FULL;
  14. db_block_checksum các giá trị sau được cho phép: OFF|TYPICAL|FULL;

Một người có kinh nghiệm trong việc duy trì cơ sở dữ liệu Oracle chắc chắn có thể nói những gì và nên đặt những giá trị nào, từ các tham số đã chỉ định và các giá trị chấp nhận được của chúng, để đạt được năng suất cao hơn của cơ sở dữ liệu khi làm việc với dữ liệu được chỉ định bởi mã ứng dụng ở trên.

Nhưng.

Mục đích của công việc trong phòng thí nghiệm là chỉ ra rằng chính thuật toán tối ưu hóa sẽ làm rõ điều này cho chúng ta tương đối nhanh chóng.

Đối với chúng tôi, tất cả những gì còn lại là xem xét tài liệu, thông qua hệ thống có thể tùy chỉnh, vừa đủ để tìm ra những thông số cần thay đổi và trong phạm vi nào.
Ngoài ra: mã hóa mã sẽ được sử dụng để làm việc với hệ thống tùy chỉnh của thuật toán tối ưu hóa đã chọn.

Vì vậy, bây giờ về mã.
Tôi đã nói ở trên về cran-r, tức là: tất cả các thao tác với hệ thống tùy chỉnh đều được sắp xếp dưới dạng tập lệnh R.

Nhiệm vụ thực tế, phân tích, lựa chọn theo giá trị số liệu, vectơ trạng thái hệ thống: đây là một gói GA (документация)
Gói này, trong trường hợp này, không phù hợp lắm, theo nghĩa là nó mong đợi các vectơ (nhiễm sắc thể, nếu tính theo gói) sẽ được chỉ định ở dạng chuỗi số có phần phân số.

Và vectơ của tôi, từ các giá trị của tham số cài đặt: đây là 14 đại lượng - số nguyên và giá trị chuỗi.

Tất nhiên, có thể dễ dàng tránh được vấn đề này bằng cách gán một số số cụ thể cho các giá trị chuỗi.

Vì vậy, cuối cùng, phần chính của tập lệnh R trông như thế này:

Gọi 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

Ở đây, với sự giúp đỡ lower и upper thuộc tính chương trình con ga về cơ bản, một khu vực của không gian tìm kiếm được chỉ định, trong đó việc tìm kiếm sẽ được thực hiện đối với một vectơ (hoặc các vectơ) mà sẽ thu được giá trị tối đa của hàm thể dục.

Chương trình con ga thực hiện tìm kiếm tối đa hóa hàm thích nghi.

Vậy thì, hóa ra là, trong trường hợp này, điều cần thiết là hàm thích nghi, hiểu vectơ là một tập hợp các giá trị cho các tham số nhất định của subd, sẽ nhận được số liệu từ subd.

Đó là: có bao nhiêu, với một thiết lập subd nhất định và tải nhất định trên subd: subd xử lý các giao dịch mỗi giây.

Nghĩa là, khi mở ra, nhiều bước sau phải được thực hiện bên trong chức năng thể dục:

  1. Xử lý vectơ đầu vào của các số - chuyển đổi nó thành giá trị cho các tham số dữ liệu con.
  2. Nỗ lực tạo ra một số nhóm làm lại có kích thước nhất định. Hơn nữa, nỗ lực có thể không thành công.
    Các nhóm tạp chí đã tồn tại trong phân khu, với số lượng và quy mô nhất định, vì sự thuần khiết của thử nghiệm - d.b. đã xóa.
  3. Nếu điểm trước thành công: chỉ định giá trị của các tham số cấu hình cho cơ sở dữ liệu (một lần nữa: có thể xảy ra lỗi)
  4. Nếu bước trước thành công: dừng subd, khởi động subd để các giá trị tham số mới chỉ định có hiệu lực. (một lần nữa: có thể có trục trặc)
  5. Nếu bước trước thành công: thực hiện kiểm tra tải. lấy số liệu từ subd.
  6. Đưa subd về trạng thái ban đầu, tức là xóa các nhóm nhật ký bổ sung, trả lại cấu hình cơ sở dữ liệu con ban đầu để hoạt động.

Mã chức năng thể dục

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

Cái đó. tất cả công việc: được thực hiện trong chức năng thể dục.

Chương trình con ga xử lý các vectơ, hay chính xác hơn là nhiễm sắc thể.
Trong đó, điều quan trọng nhất đối với chúng ta là việc lựa chọn các nhiễm sắc thể có gen mà hàm thích nghi tạo ra các giá trị lớn.

Về bản chất, đây là quá trình tìm kiếm bộ nhiễm sắc thể tối ưu bằng cách sử dụng vectơ trong không gian tìm kiếm N chiều.

Rất rõ ràng, chi tiết một lời giải thích, với các ví dụ về mã R, công việc của thuật toán di truyền.

Tôi muốn lưu ý riêng hai điểm kỹ thuật.

Các cuộc gọi phụ trợ từ hàm evaluate, ví dụ: dừng-bắt đầu, thiết lập giá trị của tham số phụ, được thực hiện dựa trên cran-r chức năng system2

Với sự trợ giúp của nó: một số tập lệnh hoặc lệnh bash được gọi.

Ví dụ:

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

Điểm thứ hai là đường thẳng evaluate chức năng, với việc lưu một giá trị số liệu cụ thể và vectơ điều chỉnh tương ứng của nó vào tệp nhật ký:

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

Điều này rất quan trọng vì từ mảng dữ liệu này, sẽ có thể thu được thông tin bổ sung về thành phần nào của vectơ điều chỉnh có ảnh hưởng lớn hơn hoặc ít hơn đến giá trị số liệu.

Nghĩa là: sẽ có thể tiến hành phân tích nhập thuộc tính.

Vậy điều gì có thể xảy ra?

Ở dạng biểu đồ, nếu bạn sắp xếp các bài kiểm tra theo thứ tự số liệu tăng dần, hình ảnh sẽ như sau:

Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa

Một số dữ liệu tương ứng với các giá trị cực trị của số liệu:
Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa
Ở đây, trong ảnh chụp màn hình có kết quả, tôi sẽ làm rõ: các giá trị của vectơ điều chỉnh được đưa ra dưới dạng mã hàm thể dục, không phải dưới dạng danh sách số của các tham số/phạm vi của các giá trị tham số đã được lập công thức ở trên trong văn bản.

Tốt. Nhiều hay ít, ~ 8 nghìn tps: một câu hỏi riêng.
Trong khuôn khổ công việc của phòng thí nghiệm, con số này không quan trọng, điều quan trọng là động lực học, giá trị này thay đổi như thế nào.

Sự năng động ở đây là tốt.
Rõ ràng là có ít nhất một yếu tố ảnh hưởng đáng kể đến giá trị của số liệu, thuật toán ga, sắp xếp thông qua các vectơ nhiễm sắc thể: được bao phủ.
Đánh giá bằng động lực khá mạnh mẽ của các giá trị đường cong, có ít nhất một yếu tố nữa, mặc dù nhỏ hơn đáng kể, nhưng có ảnh hưởng.

Đây là nơi bạn cần nó attribute-importance phân tích để hiểu những thuộc tính nào (trong trường hợp này là các thành phần của vectơ điều chỉnh) và mức độ ảnh hưởng của chúng đến giá trị số liệu.
Và từ thông tin này: hiểu những yếu tố nào bị ảnh hưởng bởi những thay đổi trong các thuộc tính quan trọng.

chạy attribute-importance có thể theo những cách khác nhau.

Với những mục đích này, tôi thích thuật toán randomForest Gói R cùng tên (документация)
randomForest, theo tôi hiểu công việc của anh ấy nói chung và cách tiếp cận đánh giá tầm quan trọng của các thuộc tính nói riêng, xây dựng một mô hình nhất định về sự phụ thuộc của biến phản hồi vào các thuộc tính.

Trong trường hợp của chúng tôi, biến phản hồi là số liệu thu được từ cơ sở dữ liệu trong các thử nghiệm tải: tps;
Và thuộc tính là thành phần của vectơ điều chỉnh.

Ở đây randomForest đánh giá tầm quan trọng của từng thuộc tính mô hình bằng hai số: %IncMSE - sự hiện diện/vắng mặt của thuộc tính này trong một mô hình sẽ thay đổi chất lượng MSE của mô hình này như thế nào (Lỗi bình phương trung bình);

Và IncNodePurity là một con số phản ánh mức độ tốt, dựa trên các giá trị của thuộc tính này, một tập dữ liệu với các quan sát có thể được phân chia, sao cho trong một phần có dữ liệu với một giá trị của số liệu được giải thích và phần còn lại với một giá trị khác của số liệu.
Chà, đó là: đây là thuộc tính phân loại ở mức độ nào (tôi đã thấy lời giải thích rõ ràng nhất bằng tiếng Nga trên RandomForest đây).

Mã R công nhân-nông dân để xử lý tập dữ liệu có kết quả kiểm tra tải:

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

Bạn có thể trực tiếp chọn các siêu tham số của thuật toán bằng tay và tập trung vào chất lượng của mô hình, chọn một mô hình đáp ứng chính xác hơn các dự đoán trên tập dữ liệu xác thực.
Bạn có thể viết một số loại hàm cho công việc này (nhân tiện, một lần nữa, sử dụng một số loại thuật toán tối ưu hóa).

Bạn có thể sử dụng gói R caret, vấn đề không quan trọng.

Kết quả là, trong trường hợp này, thu được kết quả sau để đánh giá mức độ quan trọng của các thuộc tính:

Phương pháp chọc khoa học hoặc cách chọn cấu hình cơ sở dữ liệu bằng điểm chuẩn và thuật toán tối ưu hóa

Tốt. Vì vậy, chúng ta có thể bắt đầu phản ánh toàn cầu:

  1. Hóa ra điều quan trọng nhất, trong những điều kiện thử nghiệm này, là tham số commit_wait
    Về mặt kỹ thuật, nó chỉ định chế độ thực thi của thao tác io ghi dữ liệu làm lại từ bộ đệm nhật ký subdb vào nhóm nhật ký hiện tại: đồng bộ hoặc không đồng bộ.
    Giá trị nowait điều này dẫn đến sự gia tăng gần như theo chiều dọc trong giá trị của chỉ số tps: đây là việc đưa chế độ io không đồng bộ vào các nhóm làm lại.
    Một câu hỏi riêng là liệu bạn có nên thực hiện việc này trong cơ sở dữ liệu thực phẩm hay không. Ở đây tôi hạn chế chỉ nói rõ: đây là một yếu tố quan trọng.
  2. Điều hợp lý là kích thước bộ đệm nhật ký của subd: hóa ra là một yếu tố quan trọng.
    Kích thước của bộ đệm nhật ký càng nhỏ thì khả năng đệm của nó càng ít, nó càng thường xuyên bị tràn và/hoặc không có khả năng phân bổ một vùng trống trong đó cho một phần dữ liệu oxy hóa khử mới.
    Điều này có nghĩa là: sự chậm trễ liên quan đến việc phân bổ không gian trong bộ đệm nhật ký và/hoặc chuyển dữ liệu làm lại từ đó vào các nhóm làm lại.
    Tất nhiên, những sự chậm trễ này sẽ ảnh hưởng đến thông lượng của cơ sở dữ liệu cho các giao dịch.
  3. Thông số db_block_checksum: à, nói chung thì rõ ràng - việc xử lý giao dịch dẫn đến sự hình thành các khối nhỏ trong bộ đệm đệm của cơ sở dữ liệu con.
    Trong đó, khi kiểm tra tổng kiểm tra các khối dữ liệu được bật, cơ sở dữ liệu phải xử lý - tính toán các tổng kiểm tra này từ phần thân của khối dữ liệu, kiểm tra chúng với những gì được ghi trong tiêu đề khối dữ liệu: khớp/không khớp.
    Công việc như vậy, một lần nữa, không thể làm chậm quá trình xử lý dữ liệu, và theo đó, tham số và cơ chế thiết lập tham số này trở nên quan trọng.
    Đó là lý do tại sao nhà cung cấp cung cấp, trong tài liệu về tham số này, các giá trị khác nhau cho nó (tham số) và lưu ý rằng có, sẽ có tác động, nhưng, bạn có thể chọn các giá trị khác nhau, tối đa là “tắt” và tác động khác nhau.

Vâng, một kết luận toàn cầu.

Nhìn chung, cách tiếp cận này tỏ ra khá hiệu quả.

Anh ta khá cho phép mình, trong giai đoạn đầu của quá trình thử nghiệm tải của một hệ thống dịch vụ nhất định, để chọn cấu hình tối ưu (hệ thống) của nó cho tải, không đi sâu vào chi tiết cụ thể của việc thiết lập hệ thống cho tải.

Nhưng nó không loại trừ nó hoàn toàn - ít nhất là ở mức độ hiểu biết: hệ thống phải biết về “các nút điều chỉnh” và phạm vi xoay cho phép của các nút này.

Cách tiếp cận sau đó có thể nhanh chóng tìm ra cấu hình hệ thống tối ưu.
Và dựa trên kết quả thử nghiệm, có thể thu được thông tin về bản chất của mối quan hệ giữa các chỉ số hiệu suất hệ thống và giá trị của các tham số cài đặt hệ thống.

Tất nhiên, điều này sẽ góp phần tạo ra sự hiểu biết rất sâu sắc về hệ thống, hoạt động của nó, ít nhất là trong một tải nhất định.

Trong thực tế, đây là sự trao đổi giữa chi phí tìm hiểu hệ thống tùy chỉnh với chi phí chuẩn bị thử nghiệm hệ thống đó.

Tôi muốn lưu ý riêng: trong phương pháp này, mức độ phù hợp của việc kiểm tra hệ thống với các điều kiện vận hành mà nó sẽ có trong hoạt động thương mại là cực kỳ quan trọng.

Cảm ơn bạn đã quan tâm và thời gian của bạn.

Nguồn: www.habr.com

Thêm một lời nhận xét