ちゃなべの備忘録

ほぼ備忘録です。

ISUCON本を見ながら書いたやつら【備忘録】

はじめに

これを読みながら勉強している備忘録

https://amzn.asia/d/6bd2FtXamzn.asia

1-2章

読んだ、2章で Prometheus を紹介していたが、実際に触ってみたいのであとで戻ってこよう。

3章

private-isuの準備

これを用いながら、いろいろチューニングしていく。

github.com

dockerで立ち上げたいんだけど、なんかうまく行かない。

→ 立ち上がってたわ。portがないところだった。

次に、nginxのログの設定を終わらせて、ログの解析に入る。

alpとabの準備と実行

alpというものを使うらしいが、localにinstallしなくなかったので、新しくcontainerを立ち上げてそこに入れた。

# 以下を追加
  bench:
    build: bench/
    container_name: isu-bench
    volumes:
      - ./logs/nginx:/app/src/logs/nginx
    working_dir: /app/src
    tty: true
FROM alpine:latest

# alpのinstall
RUN apk add curl unzip
RUN curl -L -O https://github.com/tkuchiki/alp/releases/download/v1.0.21/alp_linux_amd64.zip
RUN unzip alp_linux_amd64.zip
RUN mv alp /usr/bin/alp && rm -rf alp_linux_amd64.zip

# abのinstall
RUN apk add apache2-utils

これで、立ち上げてやってみる。

#alpを動かす。
$ alp json --file logs/nginx/access.log
+-------+-----+-----+-----+-----+-----+--------+----------------------+-------+-------+-------+-------+-------+-------+-------+--------+-------------+-------------+-------------+-------------+
| COUNT | 1XX | 2XX | 3XX | 4XX | 5XX | METHOD |         URI          |  MIN  |  MAX  |  SUM  |  AVG  |  P90  |  P95  |  P99  | STDDEV |  MIN(BODY)  |  MAX(BODY)  |  SUM(BODY)  |  AVG(BODY)  |
+-------+-----+-----+-----+-----+-----+--------+----------------------+-------+-------+-------+-------+-------+-------+-------+--------+-------------+-------------+-------------+-------------+
| 1     | 0   | 1   | 0   | 0   | 0   | GET    | /posts/10002         | 0.080 | 0.080 | 0.080 | 0.080 | 0.080 | 0.080 | 0.080 | 0.000  | 1948.000    | 1948.000    | 1948.000    | 1948.000    |
| 1     | 0   | 0   | 1   | 0   | 0   | POST   | /login               | 0.058 | 0.058 | 0.058 | 0.058 | 0.058 | 0.058 | 0.058 | 0.000  | 0.000       | 0.000       | 0.000       | 0.000       |
| 1     | 0   | 1   | 0   | 0   | 0   | GET    | /login               | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 | 0.001 | 0.000  | 1166.000    | 1166.000    | 1166.000    | 1166.000    |
| 2     | 0   | 0   | 2   | 0   | 0   | GET    | /img/ajax-loader.gif | 0.005 | 0.010 | 0.015 | 0.007 | 0.010 | 0.010 | 0.010 | 0.003  | 0.000       | 0.000       | 0.000       | 0.000       |
| 2     | 0   | 0   | 2   | 0   | 0   | GET    | /css/style.css       | 0.023 | 0.028 | 0.051 | 0.026 | 0.028 | 0.028 | 0.028 | 0.003  | 0.000       | 0.000       | 0.000       | 0.000       |
| 2     | 0   | 0   | 2   | 0   | 0   | GET    | /favicon.ico         | 0.006 | 0.006 | 0.012 | 0.006 | 0.006 | 0.006 | 0.006 | 0.000  | 0.000       | 0.000       | 0.000       | 0.000       |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9991.jpg      | 0.002 | 0.016 | 0.027 | 0.007 | 0.016 | 0.016 | 0.016 | 0.006  | 153638.000  | 153645.000  | 614571.000  | 153642.750  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9988.jpg      | 0.002 | 0.010 | 0.023 | 0.006 | 0.010 | 0.010 | 0.010 | 0.003  | 111647.000  | 111647.000  | 446588.000  | 111647.000  |
| 4     | 0   | 0   | 4   | 0   | 0   | GET    | /js/main.js          | 0.005 | 0.025 | 0.049 | 0.012 | 0.025 | 0.025 | 0.025 | 0.008  | 0.000       | 0.000       | 0.000       | 0.000       |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/10000.png     | 0.036 | 0.094 | 0.245 | 0.061 | 0.094 | 0.094 | 0.094 | 0.023  | 1057874.000 | 1057904.000 | 4231558.000 | 1057889.500 |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9997.jpg      | 0.023 | 0.065 | 0.192 | 0.048 | 0.065 | 0.065 | 0.065 | 0.016  | 176577.000  | 176577.000  | 706308.000  | 176577.000  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9993.jpg      | 0.006 | 0.035 | 0.071 | 0.018 | 0.035 | 0.035 | 0.035 | 0.011  | 85639.000   | 85646.000   | 342563.000  | 85640.750   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9994.jpg      | 0.007 | 0.057 | 0.113 | 0.028 | 0.057 | 0.057 | 0.057 | 0.022  | 105271.000  | 105278.000  | 421105.000  | 105276.250  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9995.jpg      | 0.007 | 0.062 | 0.131 | 0.033 | 0.062 | 0.062 | 0.062 | 0.021  | 123497.000  | 123497.000  | 493988.000  | 123497.000  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /                    | 0.782 | 1.001 | 3.551 | 0.888 | 1.001 | 1.001 | 1.001 | 0.080  | 34708.000   | 35496.000   | 139629.000  | 34907.250   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9990.jpg      | 0.004 | 0.007 | 0.022 | 0.005 | 0.007 | 0.007 | 0.007 | 0.001  | 102493.000  | 102501.000  | 409982.000  | 102495.500  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9989.jpg      | 0.002 | 0.010 | 0.020 | 0.005 | 0.010 | 0.010 | 0.010 | 0.003  | 107584.000  | 107584.000  | 430336.000  | 107584.000  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9996.jpg      | 0.008 | 0.050 | 0.086 | 0.021 | 0.050 | 0.050 | 0.050 | 0.017  | 375194.000  | 375218.000  | 1500848.000 | 375212.000  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9986.jpg      | 0.002 | 0.010 | 0.020 | 0.005 | 0.010 | 0.010 | 0.010 | 0.003  | 86701.000   | 86732.000   | 346867.000  | 86716.750   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9987.jpg      | 0.005 | 0.014 | 0.041 | 0.010 | 0.014 | 0.014 | 0.014 | 0.003  | 367761.000  | 367792.000  | 1471075.000 | 367768.750  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9985.jpg      | 0.003 | 0.011 | 0.031 | 0.008 | 0.011 | 0.011 | 0.011 | 0.003  | 83357.000   | 83364.000   | 333448.000  | 83362.000   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9983.jpg      | 0.004 | 0.015 | 0.031 | 0.008 | 0.015 | 0.015 | 0.015 | 0.004  | 98175.000   | 98198.000   | 392754.000  | 98188.500   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9981.jpg      | 0.002 | 0.010 | 0.020 | 0.005 | 0.010 | 0.010 | 0.010 | 0.003  | 81479.000   | 81493.000   | 325943.000  | 81485.750   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9982.jpg      | 0.004 | 0.006 | 0.021 | 0.005 | 0.006 | 0.006 | 0.006 | 0.001  | 150023.000  | 150046.000  | 600137.000  | 150034.250  |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9999.jpg      | 0.016 | 0.055 | 0.155 | 0.039 | 0.055 | 0.055 | 0.055 | 0.014  | 90021.000   | 90036.000   | 360099.000  | 90024.750   |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/10001.jpg     | 0.008 | 0.024 | 0.064 | 0.016 | 0.024 | 0.024 | 0.024 | 0.008  | 72217.000   | 72217.000   | 288868.000  | 72217.000   |
| 4     | 0   | 0   | 4   | 0   | 0   | GET    | /js/timeago.min.js   | 0.005 | 0.020 | 0.041 | 0.010 | 0.020 | 0.020 | 0.020 | 0.006  | 0.000       | 0.000       | 0.000       | 0.000       |
| 4     | 0   | 4   | 0   | 0   | 0   | GET    | /image/9998.jpg      | 0.013 | 0.043 | 0.107 | 0.027 | 0.043 | 0.043 | 0.043 | 0.011  | 61716.000   | 61740.000   | 246912.000  | 61728.000   |
| 5     | 0   | 5   | 0   | 0   | 0   | GET    | /image/10002.jpg     | 0.005 | 0.014 | 0.042 | 0.008 | 0.014 | 0.014 | 0.014 | 0.003  | 279915.000  | 279938.000  | 1399613.000 | 279922.600  |
+-------+-----+-----+-----+-----+-----+--------+----------------------+-------+-------+-------+-------+-------+-------+-------+--------+-------------+-------------+-------------+-------------+

# 次に、nginxのコンテナにちょっかい出す。
$ ab -c 1 -n 10 http://isu-nginx/
This is ApacheBench, Version 2.3 <$Revision: 1903618 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking webapp-app-1 (be patient).....done


Server Software:
Server Hostname:        webapp-app-1
Server Port:            8080

Document Path:          /
Document Length:        34641 bytes

Concurrency Level:      1
Time taken for tests:   7.890 seconds
Complete requests:      10
Failed requests:        0
Total transferred:      347370 bytes
HTML transferred:       346410 bytes
Requests per second:    1.27 [#/sec] (mean)
Time per request:       788.973 [ms] (mean)
Time per request:       788.973 [ms] (mean, across all concurrent requests)
Transfer rate:          43.00 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.4      0       1
Processing:   763  789  45.5    781     915
Waiting:      762  788  45.5    780     914
Total:        763  789  45.9    781     916

Percentage of the requests served within a certain time (ms)
  50%    781
  66%    784
  75%    786
  80%    789
  90%    916
  95%    916
  98%    916
  99%    916
 100%    916 (longest request)

$ tail -n 10 logs/nginx/access.log | alp json -o count,method,uri,min,avg,max
+-------+--------+-----+-------+-------+-------+
| COUNT | METHOD | URI |  MIN  |  AVG  |  MAX  |
+-------+--------+-----+-------+-------+-------+
| 10    | GET    | /   | 0.757 | 0.773 | 0.828 |
+-------+--------+-----+-------+-------+-------+

いいね。

ログファイルのローテート

これを準備

#!/bin/sh

mv /var/log/nginx/access.log /var/log/nginx/access.log.`date +%Y%m%d-%H%M%S`

nginx -s reopen

んで、 docker exec で実行すると、nginx上のlogファイルを日付をつけてコピーするようになった。

$ docker exec -it isu-nginx sh /var/log/nginx/rotate.sh

mysqlの解析

mysqldumpslowがないよぉ。

つぎに mysqldumpslowを用いてスロークエリログを読み取ってみようのコーナーだったのだが、M1macのdockerのmysql-imageには入っていなかった。

ということで、imageをこれに変えました、ここにはあったよ。

  mysql:
    image: mysql:8.0-debian
    platform: linux/amd64
    container_name: isu-mysql
.
.
.

これで、以下のコマンドが isu-mysql内でうてるようになった。

$ mysqldumpslow /var/log/mysql/mysql-slow.log

もちろんだけど、このログを出力するのにも設定がいるから、それは本を読もうね。

mysqlに入れないよぉ。

isu-mysql コンテナ内でmysqlにログインできなかったのだが、落ち着いてdocker-compose.yamlをみて、ログイン情報を読もうね。

以下の情報で行けるはずよ。

$ mysql -uroot -proot

4章

k6のinstall

これだけやっかいだった。結論は設定でできます。

services:
  nginx:
    image: nginx:1.24
    container_name: isu-nginx
    volumes:
      - ./etc/nginx/conf.d:/etc/nginx/conf.d
      - ./public:/public
      - ./logs/nginx:/var/log/nginx
    ports:
      - "80:80"
    links:
      - app

  app:
    # Go実装の場合は golang/ PHP実装の場合は php/
    build: ruby/
    container_name: isu-app
    environment:
      ISUCONP_DB_HOST: mysql
      ISUCONP_DB_PORT: 3306
      ISUCONP_DB_USER: root
      ISUCONP_DB_PASSWORD: root
      ISUCONP_DB_NAME: isuconp
      ISUCONP_MEMCACHED_ADDRESS: memcached:11211
    links:
      - mysql
      - memcached
    volumes:
      - ./public:/home/public
    init: true
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1g

  mysql:
    image: mysql:8.0-debian
    platform: linux/amd64
    container_name: isu-mysql
    environment:
      #- "TZ=Asia/Tokyo"
      - "MYSQL_ROOT_HOST=%"
      - "MYSQL_ROOT_PASSWORD=root"
    volumes:
      - mysql:/var/lib/mysql
      - ./etc/my.cnf:/etc/my.cnf
      - ./sql:/docker-entrypoint-initdb.d
      - ./logs/mysql:/var/log/mysql
    ports:
      - "3306:3306"
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1g

  memcached:
    image: memcached:1.6

  bench:
    build: bench/
    container_name: isu-bench
    volumes:
      - ./logs/nginx:/app/logs/nginx
      - ./bench/src:/app/src
    working_dir: /app/src
    tty: true

volumes:
  mysql:
FROM debian:bullseye-slim

# alpのinstall
RUN apt update && apt install -y curl unzip
RUN curl -L -O https://github.com/tkuchiki/alp/releases/download/v1.0.21/alp_linux_amd64.zip
RUN unzip alp_linux_amd64.zip
RUN mv alp /usr/bin/alp && rm -rf alp_linux_amd64.zip

# abのinstall
RUN apt install -y apache2-utils

# k6のinstall
RUN curl -L -O https://github.com/grafana/k6/releases/download/v0.47.0/k6-v0.47.0-linux-amd64.tar.gz
RUN tar -zxvf k6-v0.47.0-linux-amd64.tar.gz
RUN mv k6-v0.47.0-linux-amd64/k6 /usr/bin/k6 && rm -rf k6-v0.47.0-linux-amd64 && rm -rf k6-v0.47.0-linux-amd64.tar.gz

結局curlでdownloadしてくるんだけど、バージョンとか環境とかが違うと

「それバイナリファイルじゃねぇから!!!」

って切れ方でバイナリファイル否定されるので注意。

5章

pt-query-digest

なんやら pt-query-digestというもんが必要らしいので、それを入れる

$  apt install percona-toolkit
$  pt-query-digest --version
pt-query-digest 3.2.1

query-digester

これのほうが便利らしいからいれる。 だけどgitを使ってinstallする方法が書かれていたので、それに乗っ取る

$ apt install git

$ cd /usr/src

$ git clone git@github.com:kazeburo/query-digester.git

$ cd query-digester
$ install query-digester /usr/local/bin

これで実行してもmysqlの権限がないよ、と怒られたので、ファイル自体の設定をいじってpasswordを入力するようにする。

- 86      open(my $pipe, '|-', $mysql, @mysqlopt, '--sigint-ignore');
+ 86      open(my $pipe, '|-', $mysql, @mysqlopt, '-p', '--sigint-ignore');

そしたらpasswordを要求されるようになるので入力しようね。

$ query-digester -duration 10
exec mysql to change long_query_time and slow_query_log_file
save slowlog to /tmp/slow_query_20230922114025.log
wait 10 seconds
Enter password:
finished capturing slowlog.
start query-digest
finished pt-query-digest.
digest saved to /tmp/slow_query_20230922114025.digest