P54 Codota

ディープラーニングによるコードの入力支援サービス
色々なIDEにサポートがされつつある

[主な機能]
・サジェスト機能
コードスニペットの提供

但し、利用するとソースコードの断片がCodotaのサーバーに送信されるため、秘匿コードとかの場合は現時点では利用しない方が無難かもしれない。

IO 2020年 08 月号 [雑誌]

IO 2020年 08 月号 [雑誌]

  • 発売日: 2020/07/18
  • メディア: 雑誌

Amazon RDS for MySQL にインポートを行うとAccess deniedと怒られる

事象

Amazon RDS for MySQLに対して、MySQL WorkbenchでData Export行ったSQLファイルをData Importを行うと以下の様なエラーが返ってくる。

ERROR 1227 (42000) at line 17: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

原因

1.

インポートしたいダンプファイルのユーザーは`user1`@`localhost`となっていた。
しかし、RDSはリモートなので、インポート先は`user1`@`%`に紐づけられていた。

2.

(書き込み対象のスキーマに対しては権限を付与していたが、)
ビューやスキーマの情報を管理するスキーマに対して権限を与えていなかった。

3.

インポートしたいダンプファイルがバイナリログモード:OFFなSQL定義であったため。
なお、AWSのサイトを確認すると以下の様な記載が存在した。
Resolve definer errors when importing to Amazon RDS MySQL using mysqldump
そこで、log_bin_trust_function_creatorsを確認したところ、1(ON)が設定されていた。

4.

SQLに記述されているPROCEDUREのDEFFINERと、Import実行時のユーザーが異なるため

対応方法

1.

テキストエディタなどでダンプファイルを直接編集する。
具体的には、`user1`@`localhost`となっている箇所を、`user1`@`%`;に書き換える。

2.

雑な設定であれば以下で対応できる。

grant all privileges on *.* to `user1`@`%`;
flush privileges;

真面目にするのであれば、以下の様な対応をすれば良い。
スキーマ(多すぎるかも…)
・information_schema
mysql
・sys
●権限
自信が無いので書けない…。

3.

インポート元のSQLファイルを加工する。
具体的には、以下の様なSQL文をコメントアウトなどして削除した状態にした。

SET @@MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
(中略)
SET @@SESSION.SQL_LOG_BIN= 0;
(中略)
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
(中略)
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
4.

実行するユーザーをDEFINERに記述しているユーザーで実行する。
もしくは、SQL文の以下の様なDEFINER=の後を実行したいユーザー名に書き換える。

CREATE DEFINER=`user1`@`%` PROCEDURE `PROCEDURE1`(IN (以下略)

P337 PythonからのMySQL接続

●Connector/Python
 Connector/Pythonには100%Pytonで記述された「Pure Python版」と、C言語C++で実装されている「C拡張版」が存在する。
 Pure Python版はPythonの実行環境さえあれば利用可能である。
 C拡張版はインストールする必要はあるが、パフォーマンスが良い。
 Connector/Pythonの他にもライブラリは存在するが、Oracle社が公式にサポートしているのはConnector/Phthonだけである。

●Connector/Pythoが対応しているMySQLPythonのバージョン
MySQL :: MySQL Connector/Python Developer Guide :: 3 Connector/Python Versions

●Connector/Pythonのインストール方法
[pipの場合]

pip install mysql-connector-python

[Anacondaの場合]

conda install -c anaconda mysql-connector-python

[それ以外の場合]
https://dev.mysql.com/downloads/ にアクセスし、「Connector/Python」をクリックし、その後パッケージをインストール

●サンプルコード

import mysql.connector

config = {
  'user' : 'hogehoge',
  'password' : 'password',
  'host' : '127.0.0.1',
  'database' : 'mysql'
}

try:
  conn = mysql.connector.connect(**config)
  print(conn.is_connected())

except mysql.connector.Error as err:
  print("VendorError:", err.errno)
  print("SQLState:", err.sqlstate)
  print("SQLException:", err.msg)

else:
  conn.close()

●主なエラー一覧
詳細は書籍に記載有

●MySQL8.0.11で発生しがちなエラー(SSL通信関連)について
 Connector/Pythonはバージョン8.0.11以降、C拡張版がデフォルトで利用される。これにより、リモートホストからMySQLサーバーに接続する際に、SSL暗号化通信が有効化される。
 SSL暗号化通信を無効化する事でエラーを解消するには、コネクション生成時に以下のパラメータを指定すれば良い。
  C拡張版の場合:ssl_disabled=True
  Pure Pythonの場合:use_ure=True

*演算子 / **演算子

日本語ドキュメント上は* 演算子(アスタリスク演算子)、** オペレータ(ダブルアスタリスクオペレータ)と表記揺れは存在したが、英語版ドキュメントには *-operator / **-operator と記載されていた。
docs.python.org
演算子を用いれば、アンパックという作業を行ってくれ、わざわざ都度代入文を記載する必要もなく、可変引数も渡すことができ便利である。
[参考リンク]
Python3.xのアスタリスク逆引き - Qiita

インターネットゲートウェイ/NATゲートウェイ/NATインスタンス

f:id:yoneyore:20200709215743j:plain
理解がごちゃ混ぜになっていたので、再整理する。
なお、インターネットゲートウェイ以外にも、Direct Connect (Gateway)、VPN GatewayVPC Peering、TransitGatewayなどいくつか存在するが、一旦ここでは割愛する。

インターネットゲートウェイ

docs.aws.amazon.com
・EC2がインターネットにアクセスするために利用する通常のコンポーネント
・当コンポーネントを利用するに加え、EC2はパブリックIP or ElasticIPをアタッチしておかないと通信は行えない
・当コンポーネントを用いる事で発生する通信料は発生しない
 但し、EC2がインターネットに出ていくためのデータ転送に対しては1GB以上は料金が発生する(インターネットからEC2に入ってくる場合は無料)
 オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS

NATゲートウェイ

docs.aws.amazon.com
・パブリックIPやElasticIPを持たないEC2がインターネットにアクセスするために利用するコンポーネント
・NATゲートウェイ自体にElasticIPを設定している事になり、外に出る時はインターネットゲートウェイが必要である
・NATゲートウェイコンポーネントに対して1時間当たり課金が発生する上、NATゲートウェイを経由するための通行料も課金される

NATインスタンス

docs.aws.amazon.com
・EC2インスタンスをNATさせるためのコンポーネントとして利用しているだけで、実態はEC2そのものである
・AMIイメージなどが提供されているのでわざわざ自前で構築しなくても比較的楽に作成はできる
・NATインスタンス自体にElasticIPを設定し、外に出る時はインターネットゲートウェイが必要である
・NATインスタンス自体はEC2をもう一つ立てて、それに対する料金が発生する格好となる

previmにChromeを指定して開くとvimが編集できなくなる

【事象】
以下の設定にて、QuickRun経由でPrevimでMarkdownを表示できる環境を構成している。
yoneyore.hatenablog.com
上記設定に従いChromeMarkdownの解析結果を表示したら、Vim側が編集できなくなる。

【対応方法】
先にChromeを開いておけば良い。
そうする事でVimは編集できるし、保存したらその結果も再描画してくれる。

マスタリングVim

マスタリングVim

CloudFront + S3 + HLS形式ストリーミングの動画サイトがカクカク再生されてしまう

構成

サーバー:CloudFront + S3構成
動画構成:mp4をHLS形式(M3U8ファイル + 複数のTSファイル)
クライアント:video.js

事象

動画を再生するとカクカク再生される

原因・理由・対策

原因1

video.jsがいけてなさそう

(理由)
video.jsの動作をChromeのdeveloper toolで眺めていたところ、どうもプリフェッチタイミングと切り替えに関する作り込みがいけてなさそうな気がした。
具体的には、プリフェッチのタイミングがTSファイルが次のに切り替わるぎりぎりな位から行い出すので、もう少し早めに動いてくれてもよさそうな気が。
(オプションパラメータで指定できるのかもしれないけど、後述するhls.jsにしたら問題解決したのでそこまで追ってない)
また、致命的なのが、切り替えタイミングの処理が何故かもたつく場合が多く、動画は既にローカルにダウンロードしているのに、何故か切り替わりに時間がかかっている。
ディスクキャッシュから再生している場合でもその事象が時たまに発生するため、ネットワーク側ではなくvideo.jsの問題と結論づけた。

(対策)
hls.jsに切り替えた。
結果、他の原因分析行わなくてもいいのではないかと思う位スムーズに再生される様になった。
Chrome developer toolで眺めていると、遅からず早からずな良きなタイミングで次の動画のプリフェッチ処理を行っていた。

原因2

TSファイルの分割単位が細かすぎる

(理由)
自分がTSファイルを作成する際に、利用しているソフトのデフォルト値(5秒)のままにしていた。
そのため、頻繁にダウンロード処理が入る & 切替処理が発生するため、カクカクする原因を生み出していた。

(対策)
5秒→15秒に変更した。
分割単位が小さいメリットとして、その動画が再生されない場合のトラフィック量を下げれるのと、もし早送りされた場合にその動画始まりまでの待ち時間を短くできるので、今の画質で3MB位に収まるサイズが15秒だったので15秒とした。
(はじめは30秒にしようとしたが、TSファイルサイズが5MB超えるとさすがに大きすぎると思ったので)

原因3

CloudFrontのヒット率が1%である

(理由)
何か自分が設定不備っているのであろうが、正直意味の分からない動きばかりする(※1)のと、原因1の対策打つ事でほぼ改善したので、こちらは一旦白旗振る事にした。

※1
基本的にはキャッシュミス(x-cache:Miss from cloudfront)が発生する。
なのに、たまにキャッシュヒットする場合もあれば、1時間すら経っていない & エッジポイント(NTR51-C1)変わってないのにすぐキャッシュアウトされてしまう。

(対策)
以下の対応を実施したのであるが、全く改善の兆しがない。
・BehaviorをDefaultのみとするのではなく、拡張子単位に定義する
・Viewer Protocol PolicyをRedirect HTTP to HTTPSからHTTPS Onlyに変更
 実験していると、何故か一時期https://~でアクセスしたリクエストはキャッシュインされないのに、http://~でアクセスしたリクエストはキャッシュされる様な事象が散見された。
 そのため、http://~でわざわざアクセスしてくる人も超レアケースかと思い、思い切って閉じたら、思い通りキャッシュされなくなってしまった。
・Allowd HTTP MethodsをGET, HEADからGET, HEAD, OPTIONSに変更
 POSTやDELETEは発行されたくないので(誤ってこちらが提供してしまっていた場合にやられるのを防ぐため)、OPTIONSのみ開放したが変化無
・MinimumTTL/MaximumTTL/DefaultTTLを2592000(約1カ月)に変更
 全く効果無
 なお、S3側のヘッダーは何も付加していないので、こちらを試す必要はあるのかもしれないが、コンソールから全部一括で行えない(ので一旦やっていない
 (CloudBerryやLambdaでやればいいだけではあるが)
・Cache Based on Selected Request Headers, Forward Cookies, Query String Forwading and CachingをNoneに設定
 これは元からそうしてる
・Smooth StreamingをYesに設定
 これをNoにはしたことないが、キャッシュされる/されないには関係ないと考えている
・Compress Objects AutomaticallyをYes→Noに設定
 変更したが効果無
 なお、クライアント端末が貧弱な可能性もありそうなので、通信経路の速さを期待して、あえてNoのままにした
Curlコマンドで事前に動画アクセス
 一時期改善が見られキャッシュインされる様になったが、1週間経ったら何故かキャッシュアウトされていた
 (想定では1カ月キャッシュインされている想定なのに…)

キャッシュアウトされたままという記事があまり見つからなかったので、手詰まり感があり、またそこまで今は困ってないので一旦調査は断念した。
結果としては、video.js → hls.jsにしたら大幅に改善した。
なお、hls.jsにした場合は、きちんと実装していないとiOSブラウザで再生ができなくなってしまうので、必ず検証しましょう(私は検証したら、見事やらかしていた[まじめに検証して良かった])。

残課題

hls.jsを用いると、偶発的ではあるが頻繁に早送り・巻戻しを行うと、Windows版のChromeでは止まってしまう現象を確認している。
但し、AndroidChromeや、iOSSafariでは特に発生していない。
オプション与えないといけないのではあろうが、他の作業進めないといけなかったので、一旦調査を止めている。