isucon10の予選に参加したお話

はじめに

2020年9月12日に開催されたisucon10の予選に3人チームで参加しました。isucon10でやったことや反省点などについて書いていきます。結果ですが、初期スコア400点だったのを最終的に900点ぐらいまで上げて終了になりました。まだまだ改善の余地があったのかなと思っています。

事前に準備していたこと

事前に以下のことをやっていました。

  • isucon9の予選問題を解く
  • new relicを使ってみる
  • デプロイ用のスクリプトとかを準備する
  • nginx秘伝のタレ作成

当日の構成

こんな感じの構成にしてがんばりました

サーバ 用途
1台目 nginx+app(nodejs)+mysql
2台目 app(nodejs)
3台目 app(nodejs)

appはエンドポイントごとに分けました。

mysqlの負荷が凄かったので1テーブル1サーバみたいな構成にするべきでした

当日の流れ

以下の順番でやっていきました。

  1. new relic導入

  2. nginx.conf秘伝のタレ導入

  3. スロークエリのログ設定

  4. botからのアクセスが来たら503を返す設定

  5. sqlの order by id を消して popularity にインデックスを貼った

  6. sql の条件文を between に書き直した

  7. nazotte の n+1 を修正 (sqlで内外判定していたのを アプリで判定するように修正した)

  8. 同期sqlを非同期化

  9. features正規化

  10. appのエンドポイントごとにサーバを振り分ける設定

反省点

思いついたことを適当に箇条書きで並べます。

  • new relicを有効活用できなかった気がする
  • DBのチューニングが全然できていなかった
    • DBを複数台構成にしていればスコアもっと上がった気がする
    • 降順インデックスや空間インデックスを使う
      • DBの勉強不足を痛感しました。。。

最後に

とても楽しいコンテストでした。運営の皆様本当にありがとうございました。

来年も多分出ます。

Splunk Appをカスタマイズする方法

Splunk Appの作り方

Splunkは目的に応じてAppを使い分けるのが一般的です。Appは以下の手順で作成することができます。

Splunkホーム画面の左にある設定ボタンを押します。

f:id:Rayleigh865:20200730213939p:plain

次に右上にある「Appの作成」というボタンを選択します。

f:id:Rayleigh865:20200730214101p:plain

App名を入力し保存します。

f:id:Rayleigh865:20200730214220p:plain

これでAppを作成することができます。先ほど作成したhotate Appを選択し、Appのカスタマイズを行います。

f:id:Rayleigh865:20200730214402p:plain

カスタマイズ方法

Appの選択後にヘッダーにある設定ボタンから「ユーザーインターフェイス」を選択します。

f:id:Rayleigh865:20200730214602p:plain

次にナビゲーションバーを選択します。

f:id:Rayleigh865:20200730214702p:plain

defaultボタンを押すと以下のような編集ページが現れます。

f:id:Rayleigh865:20200730214824p:plain

<nav search_view="search">
  <view name="search" default='true' />
  <view name="datasets" />
  <view name="reports" />
  <view name="alerts" />
  <view name="dashboards" />
</nav>

xml形式で下図の赤枠部分を設定することができます。

f:id:Rayleigh865:20200730215013p:plain

viewタグにdefaultをtrueにすることでAppを開いた時に最初に表示される項目を設定できます。 例えばダッシュボード をこの赤枠に入れたい場合は以下のように設定します。

<nav search_view="search">
  <view name="search" default='true' />
  <view name="datasets" />
  <view name="reports" />
  <view name="alerts" />
 <collection label="ダッシュボード一覧">
       <view name="hoge1" />
       <view name="hoge2" />
   </collection>
</nav>

設定保存後以下のように反映されます。

f:id:Rayleigh865:20200730215455p:plain

先ほど設定したhoge1とhoge2はダッシュボード IDです。 ダッシュボード IDを指定することで任意のダッシュボード をこの欄に表示することができます。 ダッシュボード IDはURLにて確認することができます(フォーマットは以下の通り)。

また以下のような設定をすることで外部リンクに参照することもできます。

<nav search_view="search">
  <view name="search" default='true' />
  <view name="datasets" />
  <view name="reports" />
  <view name="alerts" />
 <collection label="ダッシュボード一覧">
       <view name="hoge1" />
       <view name="hoge2" />
  </collection>
 <a href="https://ja.wikipedia.org/">wikipedia</a>
</nav>

wikipediaボタンを押すとhrefにて設定したリンクに遷移できます。 上記の設定ファイルは/opt/splunk/etc/apps/hotate/local/data/ui/nav/default.xmlで確認することもできます。

Chefの環境構築とレシピの生成方法

Chefとは

Chef(シェフ)とは、構成管理(プロビジョニング)ツールです。ユーザ作成、パッケージインストール、設定ファイル編集などの展開作業を自動化します。物理環境/仮想環境/クラウド環境などの各種インフラに対応します。

[引用] オープンソースの運用管理・運用自動化 / Chefとは より

上記に記載されている通りChefはサーバの構成管理を行うツールです。レシピと呼ばれる設定ファイルにユーザ・パッケージ等の環境を記述します。 レシピはRubyで作成します。

Chefのインストール

以下のURLを参考にインストールを行います。

docs.chef.io

macOSbrew caskでインストールを行います。

$ brew cask install chef-workstation

レシピを作成する

以下のコマンドでレシピの生成を行います

chef generate cookbook sample

するとsampleというディレクトリが生成されます。中身は以下の通りです。

.
├── CHANGELOG.md
├── LICENSE
├── Policyfile.rb
├── README.md
├── chefignore
├── kitchen.yml
├── metadata.rb
├── recipes
│   └── default.rb
├── spec
│   ├── spec_helper.rb
│   └── unit
│       └── recipes
│           └── default_spec.rb
└── test
    └── integration
        └── default
            └── default_test.rb

recipesディレクトリでレシピの作成を行います。metadata.rbではgemの依存関係などを書きます。 次に記事では実際にnginxの環境構築に関するレシピを作成していきます。

pythonで文字列から数字を抽出する

やりたいこと

あいうえお2020かきくけこ

↑ こんな文字列から

2020

↑これだけ取り出したい 正規表現を使って取り出す

プログラム

import re

def main():
  test="あいうえお2020かきくけこ"
  moji = int(re.sub("\\D", "", test))
  print(test)
  print(moji)

if __name__ == '__main__':
    main()

結果

$ python main.py

あいうえお2020かきくけこ
2020

5行目の\Dにて任意の数字以外を抽出(正規表現で表すと[^0-9])している。 re.subを使うことで文字列を空に変換している(第二引数で置換先の文字列を選べる)

GO言語でunexpected directory layoutと表示された時の対処法

問題

go run main.goなどでプログラムを実行した際に以下のようなエラーが出ることがあります。

$ go run main.go
unexpected directory layout:
    import path: _/Users/rayleigh865/Documents/src/code/web/api
    root: /Users/rayleigh865/Documents/src
    dir: /Users/rayleigh865/Documents/src/code/web/api
    expand root: /Users/rayleigh865/Documents/
    expand dir: /Users/rayleigh865/Documents/src/code/web/api
    separator: /

解決方法

このようなエラーが出た場合はimportの部分が相対参照になっているのが原因です。例えば

package main
import (
  "fmt"
  "../web/api"
)

となっていたら以下のような絶対パス($GOPATH/src以下から書く)にすると直ります。

package main
import (
  "fmt"
  "code/web/api"
)