ISUCON 12 メモ

複数代のインスタンスに一度で ssh する

セットアップの方法はこの記事を参照

blog.yuuk.io

ssh config に以下を記載。

Host isucon12-*
  User isucon
  IdentityFile "~/.ssh/id_rsa"
Host isucon12-qualify-1
  HostName *.*.*.*
Host isucon12-qualify-2
  HostName *.*.*.*
Host isucon12-qualify-3
  HostName *.*.*.*

1 ~ 3 のインスタンスに接続する時は下記コマンドを実行する。

tssh isucon12-qualify-{1..3}

Docker で起動された python アプリに New Relic APM を導入する

docs.newrelic.com

ISUCON で使用されているイメージを用いて New Relic のドキュメント通りに Dockerfile を新規に作成する。

FROM python:3.9.13-bullseye

RUN pip install --no-cache-dir newrelic

ENTRYPOINT ["newrelic-admin", "run-program"]

ビルドを実行。

docker build -t python_newrelic:latest .

ISUCON 用の Dockerfile にビルドしたイメージを使用するように変更する。

FROM python_newrelic:latest

WORKDIR /tmp
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y wget gcc g++ make sqlite3 && \
  wget -q https://dev.mysql.com/get/mysql-apt-config_0.8.22-1_all.deb && \
  apt-get -y install ./mysql-apt-config_*_all.deb && \
  apt-get -y update && \
  apt-get -y install mysql-client build-essential libssl-dev libffi-dev python3-dev cargo

RUN useradd --uid=1001 --create-home isucon
USER isucon

RUN mkdir -p /home/isucon/webapp/python
WORKDIR /home/isucon/webapp/python

ADD requirements.txt /home/isucon/webapp/python
RUN pip install -r requirements.txt

COPY --chown=isucon:isucon ./ /home/isucon/webapp/python/

CMD [ "python", "main.py" ]

環境変数で New Relic のライセンスキーを指定等を行えば準備 OK。

インデックスを作成する

EXPLAIN でクエリの調査。

EXPLAIN  SELECT player_id, MIN(created_at) AS min_created_at FROM visit_history WHERE tenant_id = 1 AND competition_id = '4447b4e1' GROUP BY player_id
+----+-------------+---------------+------------+------+---------------+---------------+---------+-------+---------+----------+------------------------------+
| id | select_type | table         | partitions | type | possible_keys | key           | key_len | ref   | rows    | filtered | Extra                        |
+----+-------------+---------------+------------+------+---------------+---------------+---------+-------+---------+----------+------------------------------+
|  1 | SIMPLE      | visit_history | NULL       | ref  | tenant_id_idx | tenant_id_idx | 8       | const | 1472344 |    10.00 | Using where; Using temporary |
+----+-------------+---------------+------------+------+---------------+---------------+---------+-------+---------+----------+------------------------------+
1 row in set, 1 warning (0.01 sec)

テーブルのスキーマ

CREATE TABLE `visit_history` (
  `player_id` VARCHAR(255) NOT NULL,
  `tenant_id` BIGINT UNSIGNED NOT NULL,
  `competition_id` VARCHAR(255) NOT NULL,
  `created_at` BIGINT NOT NULL,
  `updated_at` BIGINT NOT NULL,
  INDEX `tenant_id_idx` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8mb4;

インデックスの作成。

ALTER TABLE `visit_history` DROP INDEX tenant_id_idx;
ALTER TABLE `visit_history` ADD INDEX `tenant_id_idx` (tenant_id, competition_id, player_id);