ラズパイでルータを作る (ラズパイでhadoopクラスタを構築するための準備)

ことはじめ HPCの研究室に所属している割にはHPCっぽいことができていなくて不満なので、自分でHPCぽいことをやることにした。自分のいう「HPCぽさ」ってのは、大規模なデータ分析とか難しい処理を複数ノードを使って効率よくやることとか、まあとりあえずクラスタが好きなんすよ。 ってことでとりあえず手始めにラズパイでHadoopクラスタを構築する。その後kubernetesクラスタや、slurmクラスタも試してみる。 やることは全部で5つある。3つめと4つ目ははHadoopクラスタの構築のためではなく、MPIを使った実行も可能にするためである。勉強にはなる。 1. ラズパイのルータ化 2. クラスタネットワークに属しているノードのIPアドレスを固定 3. ノード間をシームレスで移動できるようにkeychain loginを追加 4. nfsを使ってノード間で共有ディレクトリを作る 5. hadoopの導入 ラズパイのルータ化(やることその1) 大元のLanにはsoftbankのルータを使っているが、このネットワークにラズパイクラスタを置きたくない。なので、ラズパイ一台をルータ兼マスターノードにして新しいネットワーク(172.20.2.0/24)を構築する。 ネットワークの構成 192.168.3.0/24がメインのネットワークで、この中にルータ兼マスターノードをつくる。マスターノードは2つのnicを持つが、 192.168.3.0/24側は、192.168.3.4 新しいネットワーク側(172.20.2.0/24)は172.20.2.1。 そして172.20.2.0/24の中にラズパイクラスタをいっぱい配置する。 必要な道具 ラズパイはether net ポートが1つしかない。そのためラズパイで外部からアクセス可能なLanを作るためにはもう一つ物理的なLanポートが必要になる。これには usb -> ether net変換アダプタを使う。 ifconfigの結果は次のような感じになる。 eth0がもとからついているポートでeth1が追加されたやつ。 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.3.4 netmask 255.255.255.0 broadcast 192.168.3.255 inet6 fe80::dea6:32ff:fefa:54df prefixlen 64 scopeid 0x20<link> inet6 2400:2413:121:fd00:dea6:32ff:fefa:54df prefixlen 64 scopeid 0x0<global> ether dc:a6:32:fa:54:df txqueuelen 1000 (Ethernet) RX packets 841 bytes 96345 (96.3 KB) RX errors 0 dropped 281 overruns 0 frame 0 TX packets 472 bytes 90115 (90.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 18:c2:bf:e9:3b:8d txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0がメインネットワーク側。eth1がクラスタネットワーク側。以下、新しいネットワークを作るための設定 ...

December 10, 2022 · 2 min · 367 words · Me

Vnc

https://ja.linux-console.net/?p=716#gsc.tab=0 https://www.server-world.info/query?os=Ubuntu_22.04&p=desktop&f=6 参考サイト いや、色々書いたけど、これが一番参考になります。 ref まあ書いてあることをまとめるよ 必要なソフト サーバ側 tigervnc-standalone-server 以下のコマンドでインストール可能 apt install tigervnc-standalone-server -y で、vpnサーバにクライアントからアクセスするにはパスワードが必要だよね。 そのパスワードの設定を次のコマンド出やります。 vncpasswd Password: Verify: Would you like to enter a view-only password (y/n)? n こういうのが出てきます。 このコマンドでvncサーバを起動できます。 vncserver -localhost no ポート番号の下四桁とディスプレイ番号が一致します。 その他、知っておいたほうがいいもの 実行中のvncサーバ一覧 vncserver -list output X DISPLAY # RFB PORT # RFB UNIX PATH PROCESS ID # SERVER 1 5901 2821 Xtigervnc クライアント側ではretinia? っていうubuntuにデフォで入っているやつ使えば問題ないです。はい、おつかれっす。

November 4, 2022 · 1 min · 59 words · Me

singualrityとかcudaとかnvidia-driverとかその辺で問題が起こったのでまとめておく

cuda nvidia社のGPUを使ってプログラムを書きたいときはCUDAというソフトウェア実行環境を使わないといけない。 cudaの中には、cudaプログラム用のコンパイラー(nvcc)とか、その他ライブラリ、APIも入っている。pythonのtensorflowやpytorchも内部的にはcudaの ライブラリを使っている。そのため、pythonでtensorflowを使う時、cudaのインストールが必要となる。 cuDNN 実はcuda以外にもtensorflowを実行するときに必要なライブラリがあって、それがcuDNN. cudaはgpuを使ったプログラミング全般に関する実行環境である。そのため、デフォルトでDL用のライブラリは入っていない。cuDNNはcudaで書かれたDL用のライブラリである。cuDNNを入れることでGPUで簡単にDLが可能となる。その辺分けるのめんどいから統合してほしいだけども。 nvidia-driver GPUのドライバ。ドライバはハードウェアとのやり取りをするソフト。 singularity コンテナ型仮想環境。 仮想化してくれる範囲だけど、カーネル以外は全部仮想化してくれる。 つまり、ハードに直接干渉しないソフトであれば、全部singularity内で管理してOKってこと。 singularity上でtensorflowを使ってDLをする方法 互換性の確認 上で説明したcuda,cuDNN,nvidia-driverは全部互換性がある。その確認を最初にやるべき。 nvidia-driverのインストール ubuntuだったら、 sudo apt install nvidia-driver-450 とかでインストールできる。 singularityコマンドでdocker hubからtensorflowの最新イメージを持ってくる。 sudo singularity build tensorflow.sif docker://tensorflow/tensorflow:latest-gpu-jupyter コマンドでdockerからコンテナイメージを持ってきてsifファイルをビルドしてくれる。docker->singualrityへの変換は勝手にやってくれる。 ちなみに、jupyterも入っている。singularityには二つのコンテナ型仮想環境が用意されている。sifとsandbox. sifはあとから、apt-get install 等で 新しくファイルをインストールすることが不可能なので、一番最初のビルドの時に必要なソフトすべてをインストールしておく必要がある。 一方,sandboxは環境の変更が可能だが、gpuが使えない。基本的にgpu目的で使っているのでsandboxを使うことなはいかな。 持ってきたコンテナイメージにはcudaが入っている。cuDNNは見つけられないけど、入っているのかな? ドライバーは物理環境のドライバーを共有する。 今回起こっている問題 singularity上でtensorflowを使って学習しているのだが、以下のエラーがでてGPUを使った学習がされない。 2022-10-15 18:03:49.665516: E tensorflow/stream_executor/cuda/cuda_driver.cc:265] failed call to cuInit: UNKNOWN ERROR (34) 2022-10-15 18:03:49.665581: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: hoge 2022-10-15 18:03:49.665602: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: hoge 2022-10-15 18:03:49.665709: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: NOT_FOUND: was unable to find libcuda.so DSO loaded into this program 2022-10-15 18:03:49.665746: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 520.61.5 2022-10-15 18:03:49.665954: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags. これについて、物理環境のnvidia-driverはバージョン520。一方、dockerハブから持ってきた最新のイメージに入っているcudaのバージョンが11-2。 nvidia-driver-520はcuda11-8しかサポートしていないとのこと。つまり、not compatibleだね。 これは間違いです。nvidia-driverは後方互換性があり、基本的に古いcudaのversionは全部サポートしています。 ...

October 15, 2022 · 1 min · 157 words · Me

暗号理論(授業)とOpenssl

初回はガイダンスだったので、2回目から記録をとっていく。 第2回 概要 本講義全体では、主に公開鍵暗号理論の数学的な側面について進めていくことになる。が、公開鍵が何者かわからずに理論を学んでも仕方がない、ということでそれに先立ち、公開鍵暗号が出てくるまでの歴史と公開鍵暗号が使用される場面、さらに公開鍵の問題点を説明する、という感じの流れ。 公開鍵が出てくるまでの歴史 公開鍵は、共通鍵を安全に配送するために考え出された暗号である。 つまり、公開鍵が出てくるまでの鍵はすべて共通鍵暗号方式であり、送信者と受信者で同じ鍵を共有する必要がある。 シーザー暗号 ローマの軍人、ユリウス・シーザーが考え出した暗号。平文のアルファベットをアルファベット順でn文字シフトさせる。送信者と受信者でシフトする文字数n(鍵)を共有する必要がある。 問題点としては、鍵の数が25しかないので破るのが簡単ということ。 換字暗号 シーザー暗号を一般化したものとして、生み出された暗号。シーザー暗号では鍵に対して全ての文字をnシフトしていた。一方、この暗号は,文字1文字に対して暗号文を一対一に写像する。可能な鍵の種類はpermutation(25)になる。 問題点としては、平文と暗号文の対が流出すると鍵が破られること、また、同じ鍵でやり取りを続けていると規則性が見つかってしまうことがある。 バーナム暗号 発明されたのは、1918年。このころは電信がすでに発達していた。つまり、「ビット」という概念が存在した。 ビット列で生成された平文と同じ長さの鍵を用意する。平文と鍵のビット同士の排他的論理和をとることで暗号文が生成される。復号には同じ鍵を用いて、暗号文と鍵の排他的論理和をとる。 自分は、このバーナム暗号が現代の共通鍵暗号方式でも使われいてると思っていたが、どうやら違うようです。後ほど共通鍵のセクションで説明する鍵が現代では使われているみたい。授業ではバーナム暗号が使われない理由として、共通鍵を共有するのが難しいと言っていたが、それは全部の共通鍵に共通することじゃないか?と思った。なぜ現代でバーナム暗号が共通鍵に使われないかは調べてみる価値があるかもしれない。 その他、古典的な暗号技術 エニグマ暗号器、ローレンツ暗号器の二つが説明されていたが、原理についてはそこまで説明していなかった。 現代の暗号技術 共通鍵暗号 今まで説明してきたのも全部共通鍵暗号だが、現代ではさらに強力な共通鍵暗号が考案されているらしい。 1977年にDESという共通鍵暗号が考案され、さらに2001年にAESというさらに強力な暗号が考案された。 公開鍵暗号 ここまで共通鍵をずっと説明してきたが,共通鍵を使った暗号系の問題に「どのように安全に共通鍵を2者間で共有するか」がある。これを鍵配送問題という。 鍵配送問題を解決するために発明されたのが「公開鍵暗号方式」である。さらに、公開鍵暗号方式の特徴を活かして認証や署名をすることもできる。 じつは、公開鍵にも問題点はあるが、それを解決する手段として、公開鍵を使った署名が行われる(デジタル証明書)。後ほど説明する。 公開鍵暗号方式では、秘密鍵と公開鍵という二つの鍵をペアで生成する。 公開鍵で暗号化された暗号文は、秘密鍵でしか復号できない。この逆も存在し、秘密鍵で暗号化された暗号文は公開鍵でしか復号できない。この特徴を用いることで2者間で安全に情報のやり取りができるようになる。 公開鍵暗号方式ではRSA暗号が使われる。「非常に大きな2つの素数の積の素因数分解が原理上不可能である」性質を用いているため、鍵の長さが非常に長いのが特徴で、現在、RSA暗号の安全性を担保する為には2048bitの鍵が必要となっている。 原理的には、すべての通信を公開鍵暗号で行うことも可能だが、暗号、復号のコストが大きいため、共通鍵を公開鍵暗号方式で交換した後は、共通鍵で暗号通信をするのが一般的である。 認証と署名についても説明したいと思う。 認証とは、「公開鍵のペアである秘密鍵が本物であるか」を証明するための仕組み。原理は簡単で、送信者は元文を公開鍵で暗号化し、暗号文を受信者に送る。受信者が秘密鍵で復号してそれを送信者に送り返す。元文と秘密鍵で復号されて送られてきた文が同じであれば受信者がもっている秘密鍵が本物であることが証明できる。つまり、送信相手が安全ということが保証される。 署名とは、「送られてきたデータが改ざんされていないこと」を証明するための仕組み。AがBになにか情報を送りたいときに署名をつかう例で説明する。 まず、AとBの両者で共通のハッシュ関数を用意する。Aはハッシュ関数に送信したい情報を入れてハッシュ値をえる。そのハッシュ値を秘密鍵で暗号化する。Aは暗号化されたハッシュ値と平文をBに送る。Bは、1)送られてきた平文を公開されているハッシュ関数にかけてハッシュ値を得る。さらに,2)Aから送られてきた暗号化されたハッシュ値を公開鍵を使って復号する。この二つの値が一致すれば、Aが送ってきた文書に改ざんがないことが証明できる。 (同時に、認証もできている気がするのだが) 公開鍵暗号方式を用いて共通鍵を交換し、その共通鍵を使って通信をすれば安全なように思える。しかし、AさんとBさんの間にXという攻撃者が入る、man in the middle attackというものがある。これは、 AがBに自ら公開鍵を渡して公開鍵暗号による通信を行うとすると、XはAがBに送った公開鍵を取得し、Bには代わりに自分の公開鍵をAのものと偽って送信する。Bは(Aのものと思い込んでいる)Xの公開鍵で暗号化したデータをAに送信する(が実際はXがBの情報を不正に入手することになる)。 という攻撃手法。 つまり、公開鍵暗号方式では、「一般公開されているように見える公開鍵が、目的としている人の公開鍵である保証がない」という問題点が存在する。 この問題を解決するために、「公開鍵暗号基盤(Publick Key Infrastructure)」が整備された。 具体的には、「公開鍵が本人のものであることを証明する機関」を設けた。この機関を認証局(CA)という。 例えとして、Aが自分の公開鍵の正当性を保証する流れを考える。 Aは公開鍵が本物であることを証明するために、CA認証局に自分の公開鍵を渡す。CAは、Aから渡された公開鍵が、Aの秘密鍵のペアであることを上で説明した認証等の技術を使って確認する。その後、CAはCAが持っている秘密鍵を用いてAの公開鍵をハッシュ化し、さらに暗号化する(署名)。この、ハッシュ化されて、暗号化された公開鍵がデジタル証明書である。技術的には「認証局の秘密鍵・公開鍵を用いた署名」を使っている。 ここでBがAの公開鍵が本当にBのものであるかを確認したいときには、Aのデジタル証明書をCAの公開鍵で復号する。復号された公開鍵のハッシュ値とAが本物であると宣言する公開鍵のハッシュ値が一致すれば、その公開鍵は本当にAのものであることが証明される。 なお、上で説明しているハッシュ値を計算するための「ハッシュ関数」は公開されているものである。つまり、署名がどのようなハッシュ関数を用いて生成されたかは公開されている。規格化されているということ。 例えば、SHA-1は公開されているハッシュアルゴリズムで20バイトのハッシュ値を生成する。ソースコードはここで見られる。他には、sha-256というのもある。これは、256ビットのハッシュ値を生成する。 ちなみに、ssl化されているサイトはurlの左に鍵マークがついている。この鍵マークをクリックすると、デジタル証明書に関する情報が得られる。このサイトのデジタル証明書を例に説明していく(非常に見づらいですが。 認証局は,Let’s Encryptであることがわかる。 技術的に大事なところは、Fingerprintsのところ。これは、ハッシュ化された公開鍵ですね。SHA-256 Fingerprintは、2048bitの公開鍵を256bitにハッシュ化した時のハッシュ値。SHA-1 Fingerprintは20バイトのハッシュ値。20バイト=160ビット=40hex。 SHA-1 fingerprintを見ると、確かに40文字ある。 さらに写真は割愛するが、detaileタブで「Certificate Signature Value」が見られるが、これは認証局によって生成された、デジタル署名である。内容はこんな感じ AD B9 37 B3 F6 A5 BC B9 E8 98 8B 83 05 76 59 E6 8E 57 E5 4C E8 7B 25 7B 01 D0 A1 85 A5 06 C5 26 DD C9 FD 0E 9B 79 1E 8A 5F 42 F5 F0 8D BC 32 02 F0 DC 44 55 FF EB 2A 1B D0 62 D5 8A 6C 31 E3 09 FE C9 B6 1A 1A E5 6F 52 8B B0 91 51 EB 4D D3 64 07 48 18 B0 A8 30 99 5E 5C 7C 8B 53 F6 38 67 F8 D1 26 FC 86 A0 A0 A4 43 45 25 49 55 B0 CD 23 C2 CE CF 78 78 AB FF 1E 16 50 AC 87 44 37 10 49 B5 59 AC 11 F4 69 4E 17 05 5C C9 29 59 38 B7 A0 A8 AB B9 D6 54 0B C1 02 8B A6 42 4E 17 70 3E 89 F6 13 E5 BF C2 9C E7 23 DA 68 FB 15 EC BC C9 4B 73 6B 42 6C 41 56 E4 D9 20 94 52 AE F1 E0 BF DB B5 19 08 9D 54 1A DB E6 EF 7B 01 B2 1C 57 8C 1E BA 51 39 7C EC 0D 75 0C 61 C2 CF B1 16 61 E1 0F C7 B0 49 2A 53 10 A1 5E D5 24 A5 0A 24 9F 75 7D 10 3B 92 4F 84 77 2E DB 34 EF 2A 02 B4 98 D6 62 DB 161616 = (2**4)3 = 212 = 4096bit。 これが署名。この署名をLet’s Encryptの公開鍵で復号すると、SHA-1ハッシュが出てくるはず。 ...

October 6, 2022 · 3 min · 579 words · Me

Open VPNがつながらなくなった話。

openVPNが急につながらなくなった話。 自宅外から自宅内のサーバにアクセスする際の手段としてsshとvpnがあるが、最近はvpnで自宅ネットワークに入ることがおおい。というのも自宅にあるサーバで構築されたシステムの開発をする際、同じネットワーク内にいたほうがいろいろと作業がしやすいためである。 vpnサーバの構築にはopenVPNを使っているが、そんなopenVPNが今朝からつながらなくなった。 /etc/var/openvpn.logを見てみると以下のエラーが。 Tue Sep 27 15:36:24 2022 130.xx.xxx.xxx:61548 VERIFY ERROR: depth=0, error=CRL has expired: CN=hogehoge. error=CRL has expiredとのこと。 実はこれでつながらなくなるのが3回目である。まあ、証明書の有効期限が切れたということなので、証明書を再発行することになる。 その手順を改めてまとめる。 そもそもどうやってopenVPNサーバを立てるか このサイトを参考にVPNサーバを構築する。 一応、流れを説明する。 必要なソフトのインストール OpenVPNのインストール sudo apt install openvpn Easy RSAのダウンロード git clone https://github.com/OpenVPN/easy-rsa.git 認証鍵の生成 Easy RSAディレクトリへ移動 cd ./easy-rsa/easyrsa3 初期設定 ./easyrsa init-pki 以下のように表示されればOK init-pki complete; you may now create a CA or requests. Your newly created PKI dir is: path/to/easy-rsa/easyrsa3/pki CA証明書の生成 ./easyrsa build-ca パスフレーズを聞かれるので、パスフレーズを入力。再入力を要求されるので入力する。 sudo cp pki/ca.crt /etc/openvpn で生成された鍵を/etc/openvpnにコピー。 サーバ証明書の生成 ./easyrsa build-server-full server nopass パスフレーズは3で入力したものと同じものを入力。 生成された鍵を/etc/openvpnにコピー ...

September 27, 2022 · 2 min · 271 words · Me

Hugo server起動コマンドのメモ

hugoを使って本ブログを起動する方法を忘れるのでメモ go to /hugo_site/msdos_like sudo hugo server -p 443 --bind="0.0.0.0" --baseURL=https://ingenboy.com/alpha/ フロントではnginxがプロキシサーバの役割を果たしてくれていて、 https://ingenboy.com/alpha に届いたリクエストを、LANの http//192.168.3.20/alpha に転送する。 注意点 content/data には、 YAML、JSON、TOML、CSV をおく。ダウンロード用のファイルは別の場所に置く。 どこにおくか?というと、staticですね。ここに入れておくようにしてください。よろしくおねがいします!!

August 25, 2022 · 1 min · 22 words · Me

ルーム型オンラインマルチプレイヤーゲームの作り方

ルーム型オンラインゲームの作り方 La-keibaのAgentとバックエンドの通信にはpythonのwebsocketを使うことになっている。なぜpythonかというと、AgentはpythonのLightGBMを使ってトレーニングされた勝ち馬予測モデルを使っているから。となると、python以外に使える物はなく、仕方なくpythonを使うことにした。あと、プロセス間の通信にはhttp通信を使ってもいいんだけど、httpは一回きりの通信だし、モジュール間で双方向通信が必要なことが後々生じることもあるだろうと思いWebsocketを使うことにした。大(websocket)は小(htt)を兼ねるともいうし。(しかし、websocketの方がhttpよりオーバヘッドが大きいのも確か) websocketでも普通にJSONが扱える。 pythonを使ったwebsocket通信をするために、このサイトで勉強したのだが、これがかなり優秀だった。今まで手探りでやっていた、websocketを使ったルームベースのアプリ(ルーム型チャット等)のフレームに対する最適解を提示してくれるものとなった。このルームベースアプリケーションのフレームは様々なアプリに適応できる。ぱっと思いつくものでいうと、将棋とか、一対一で行われるゲームはそうだし、一対一ではなくとも、ルームという概念が存在するゲーム(ないしはアプリ)にはこれが適応可能である。BFだって通信に使っているプロトコルはおそらく独自の高速プロトコルだけど、全体で見た時のフレームはこれと同じだと思う。まあ、ルームを一つの物理サーバに複数立てるのではなく、1サーバに対し1ルームという感じではあると思うが。 チュートリアルでは、まるばつゲームの拡張版であるconnect4というゲームを扱った。ポイントだと思う点を以下にまとめる。 ゲームそのものを管理するゲームエンジンの存在 オブジェクト指向の真骨頂がここで使えるわけです。「ゲーム」をオブジェクトとみなして、ゲームとインタラクションする手段として、ゲームオブジェクトがメソッドを提供する。メソッドはコントローラみたいなものだね。内部の状態もゲームオブジェクトは保持する。 ルームオブジェクト そして、特定のゲームオブジェクトと、そのゲームをコントロールする権利を持つwebsocketをまとめて保持するオブジェクト(以下、ルームオブジェクト)を作り、このルームオブジェクトにidをつける。c++でもそうだったけど、websocketオブジェクトは、sendメソッドを介していつでもフロントエンドにメッセージを送れる仕様になっている。つまり、フロントエンド間(2ユーザ間)でメッセージをやり取りするには、ルームオブジェクトでそのルームに所属するwebsocketを論理的に管理し、到着したメッセージをルームに所属するwebsocketオブジェクトに返せればよい、ということになる。 JSONでメッセージのやり取り jsonメッセージの一番最初には、メッセージの種類を表す、typeを 持ってきます。そのあとは、typeに即したメッセージのやり取りをするわけですね。これがアプリケーション層でのメッセージプロトコルですね。 前に実装した独自の通信プロトコルでもそうだったけど、やはり、やり取りするメッセージの一番最初にはメッセージのタイプを持ってくるのが普通みたいですね。 タイプには例えば、initや、join、watch,playがある。initは最初にやりとりするメッセージのことでしょう。joinは、そのルームへのjoin。watchは、そのルームの観戦。playはプレイヤーの動きが入っています。typeでplayが来たら、内容に合わせてゲームオブジェクトにメッセージを送ります。 pythonのwebsocketには、 websocket.wait_closed() という、そのフロントエンドから送られてくる通信はreceiveしないけど、サーバ側からは送れる、っていう便利なメソッドがあります。これを使うことで、そのwebsocketセッションを傍観者にすることが可能です。観戦だけできるようにするってことですね。 c++にはおそらくこれがないんだけど、websocketを継承して、新しいmywebsocketクラスを作り、その中でis_player変数とかを作ることで、傍観者かそうでないか、を見分けることもできますね。これはなかなかに便利だと思います。 フロントエンド(javascript)の処理 javascriptはすでにイベントドリブンな仕様になっている。よって、イベントを登録するだけでよい。メッセージを受信した時の動作を規定する関数と、メッセージを送信した時の動作を規定する関数を作る。関数の引数にはwebsocketオブジェクトを渡しておく。その中で、websocket.addEventlistner()をする。 便利だと思った機能 便利だと思ったメソッドは、replayメソッドだね。gameオブジェクトでは、過去のムーブをすべてレコードしてある。そのレコードをひとつづつ送れば、すべて再現できるようになっている。 これは、例えば途中から入ってきた観客にこれを使って得られるメッセージを送る、といった用途で使える。 websocketとhttpの使い分けについて Websocketとhttpどっちがいいとかはなくて、それぞれ適切な用途があります。 httpは一回きりのステートレスな通信をするためのプロトコル。しかし、webアプリではhttpで通信をするけど、誰が通信してきているかを管理したいことがある。そこで、Cookieを使ってセッションを管理する。 http+Cookie = ステートフルになる。なのでhttpのセッション管理が必要なのは、フロントエンドからアプリを使いたいユーザだけ。 そして、httpはバックエンドのモジュール間の通信にも普通に使える。リクエストにJSONをのっけてpostしたり、url自体にpostする内容をのっけたりすることもできる。(RESTful)。モジュール間での通信がセッションを必要としない一度きりのもであればhttpを使えばいいし、そうでない場合はwebsocketを使えばいい。ブラウザでのゲームはステートを保持しないといけない、かつサーバからブラウザに通信が来ることがあるからhttpでは対応できなくて、Websockeを使わないといけない。

August 17, 2022 · 1 min · 30 words · Me

Db_lecture

日常的にDB触ってないとすぐ忘れてしまう件 去年の暮れか今年の初めに、DBについて一通り勉強はした。が、もう忘れてしまった。ので、もう一度勉強するか―って感じでございます。 勉強するのに使う教材は以下のyoutubeである。前回もこれを使って学んだが、今回もこれを使いたいと思う。注意点としては、このlectureは データベース理論の説明に終始していて、具体的なSQLコマンドについてはまったく触れていない点。しかし、理論についてはめちゃめちゃわかりやすく説明してくれていたと記憶している。今回は講義の内容を、この記事にまとめていきたいと思う。 データベースの基本 データベースとは データの集合 relational database とは データを2次元の表で管理するデータベースのこと。 エンティティとは、データを保持する実体。属性(attirbute) とは、エンティティが持つ実際のデータ。 例えば、「田中」というエンティティがあるとする。この田中は、年齢:24歳、名前:田中、性別:男、である。この時、「田中」というエンティティは24歳、田中、男、という属性を持つ。Relational Databaseでは、「属性」を列にして、各行を一つのエンティティにしてデータを保存する。また、エンティティは具体的な実体だが、それを抽象化した型のことをエンティティタイプという。同じく、属性もあるエンティティに対する具体的なデータだったが、これを抽象化した肩を属性タイプという。つまり、「田中」というエンティティは「人間」というエンティティタイプに属し、「人間」というエンティティタイプには「年齢」、「名前」、「性別」の属性タイプがある。 そして、relatinal databaseでは、「エンティティタイプ」をテーブルの名前に、「属性タイプ」をカラムにして管理する。 が、実際は、Entityのことをテーブルと呼ぶ。Entity Relation図も同じだよね。 DBMSとは データベースを管理するソフトウェアのこと(e.g., Mysql, Mariadb)。 データベースの操作には、queryというものを発行して、データベースに仕事を依頼する。 DBMSによってデータの扱いが非常にらくになる。例えば、ユーザテーブルで、2年以上ログインがないユーザを削除する場合、DBMSを使えば、queryによって簡単に変更を加えることが可能となる。 まあ、実際にはデータベースとDBMSの違いを意識する人は専門家くらいで、使う側はほぼ同じものだと思ってもいいよ。 SQLとは SQLとはデータベースとやり取りをするときに使われる言語のこと。特定のDBMSに使われる言語の事ではなく、もっと一般的な概念である。SQLでやることは大きく分けて二つである。 データベースの定義 database definition language (ddl) データベースの操作 datatabase manipulation language (dml) JOINがすごく大事なSQLである。なぜなら、DBMSではデータを様々なテーブルに分けて管理し、分散されたデータを一つにまとめるときにJOINを使うからである。 naming convention(名前の付け方) SQLは大文字で書く。e.g,SELECT, JOIN, INSERT, データ自体は、小文字で書く。 user_id ...

August 17, 2022 · 2 min · 229 words · Me

パーティションとファイルシステムについて簡単にまとめた

パーティションとは ディスクに作られた論理的な仕切りのこと。OSはディスク単位、およびパーティション単位でディスクを認識する。まず気をつけたいのがパーティション=ファイルシステムではないということ。パーティションは、文字通り物理的なディスク上に作られた論理的な仕切り。そして、ファイルシステムはパーティションごとに作られ、OSに認識される。さらに、ファイルシステムっていうのは、データの置き場所だけではなく、そこからデータを取り出すソフトの部分も指すということは肝に銘じておきたい。 パーティションテーブル(MBRとGPT) mbr,gptのはなし。 ディスクの先頭にかかれたセクター(512bit)は特別な領域である。ここにはディスク上のパーティションの構成情報を格納しているパーティションテーブルが存在する。パーティションテーブルには様々なフォーマットが存在するが、現代、最も使われているのはMBRとGPTである。だが、MBRには2つの大きな制限がある。作成可能なパーティションの最大容量の制限と、ブートモードの制限である。 パーティションの最大容量の制限は、パーティションのセクタ管理に使われるbit数が原因である。MBRはセクタ管理に32bitを使っている。1セクタ=512バイトであるため、2^(9+32) = 2048.0Gbyteということになる。一方、GPTは2^64byteまでパーティションを作ることが可能である。 また、ブートモードの違いに関しては、近年のUEFIはMBRに対応していないため、MBR形式のディスクにインストールされたOSはUEFIのマザーボードではブートが不可能となる。 fdiskを使ってハードディスクにパーティションを作る(GPTを作る場合はgdiskを使う) Linux上でMBRにフォーマットされたパーティションをファイルシステムの一部に組み込むまでの流れを説明する。なお、例ではfdiskを使っているが、GPTでフォーマットされたパーティションを利用する場合はgdiskコマンドを利用すること。 デバイス一覧表示 fdisk -l 特定デバイスの詳細表示 fdisk -l /dev/sda 特定デバイスのパーティション作成 fdisk /dev/sda パーティション作成後にカーネルにパーティションテーブルを認識させる リブートするか、 sudo partprobe /dev/sdc これをしないと、次のファイルシステムを作れない。 ファイルシステム作成 パーティションを作ってもファイルシステムを作らないとOSはディスクにファイルを保存できない。 よって、ファイルシステムを作る。 sudo mkfs.ext4 /dev/sdc1 これは結構大事なポイントです。 ちなみに、ここでext4ではなく、xfsを作りたい場合は次のようにします。 sudo mkfs.xfs /dev/sdc1 って感じですね。 ちなみにこのmkfsで作れるのは、linuxにデフォルトでインストールされているファイルシステムのみです。 例えば、vfatとか、minixとか、ext4とかですね。分散ファイルシステムであるlustreとか、 広域分散ファイルシステムのchfsとか (つくばの建部先生が作ったやつですね) をインストールしたい場合は、まったく別のアプローチをとる必要があることを承知してください。よろしくお願いします。 ちなみにちなみに、上のでxfsを作ったときの出力結果をこちらに置いておきます。 meta-data=/dev/sdb2 isize=512 agcount=4, agsize=54985734 blks = sectsz=4096 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 data = bsize=4096 blocks=219942934, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=107394, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 osのファイルシステムへのマウント sudo mount /dev/sdc1 /mnt/disk1 とかでマウントされる。 ...

August 12, 2022 · 1 min · 176 words · Me

データベース実体の保存先の変更

ことはじめ データベースを使ったアプリを作ろうとしているのだが、rootディレクトリ以下がマウントされているSSDの容量が圧迫されており、データベースの実体の保存先を外部HHDに移さないといけなくなった。ので、備忘録もかねて移し方を解説していく。 データベースの実体 Mysqlで管理されているデータベースの実体は結局はファイルである。そのファイルをどこに置くのかは /etc/mysql/mysql.conf.d/ 以下のファイルで定義されている。デフォルトでは /var/lib/mysql がmysqlのデータベースの実体が置かれる場所となる。 データベースの実体の保存場所の変更 データベースの実体の保存場所をhddに移動させる方法を解説する。新しくdbの実体を保存するhddを、 /dev/sda1 とする。なお、hddをファイルシステムに認識させるには、パーティションを作成し、その上にファイルシステムを作らないといけない。これについては別の記事を参照すること。 多くの参考サイトは以下のコマンドを打つだけでHDDにデータの保存先を変更できると書いてある。 sudo mount /dev/sda1 /var/lib/mysql しかし、これは間違いである。実際は、/var/lib/mysqlのすべての内容を一度/dev/sda1にコピーする必要がある。 なぜなら、/var/lib/mysql以下にはmysqlが動作するために必要なモジュールやファイル一式が格納されているからである。 よって、まず初めに、mysqlデーモンを停止する。そして適当なポイント(e.g., /mnt/mnt_db/)に/dev/sda1をマウントし、/var/lib/mysqlをまるっと持ってくる。 sudo systemctl stop mysql.servive sudo mount /dev/sda1 /mnt/mnt_db cp -rp /var/lib/mysql/* /mnt/mnt_db ここまで来て初めて、 sudo mount /dev/sda1 /var/lib/mysql でマウントする。 sudo systemctl start mysql.service で再起動すれば問題なくできるはずである。 mysqlにログインしてデータベース作成、ユーザに権限を与え、外部アクセスを可能にするまで 外からデータベースにアクセスする方法。意外と手間取ったから、軽く流れを書いておく。 まずはローカルで、rootでmariadbにアクセス create database name identified by 'password'; でデータベースを作る。その後、外部アクセス用のユーザを作る。 作り方は、 create user user_name; そして、先ほど作ったデータベースの権限を今作ったユーザに与える。 こんな感じで。 そのあと、やることとしては、データベース用のポート解放(3306)。あと設定ファイルの変更 /etc/mysql/conf でbind=127.0.0.1が設定されていると特定のアドレスからしかアクセス出来なくなるのでコメントアウトすること。 しかし実際に運用するときはセキュリティを高めるために通信を許可するアドレスを設定したほうがいい。 その他、mysqlで忘れがちなこと localhostでのログイン方法 ルートでログインする際: sudo mysql -u root -p ...

August 12, 2022 · 1 min · 102 words · Me