koji/メガネ男の日誌

日々の学び、活動状況を記録します。仕事のことは少なめ。

「はじめてのパターン認識」を読む 第1章 はじめに

f:id:kj_man666:20200505125428j:plain

はじめてのパターン認識 を1章ずつ読んでまとめたいと思います。

1.1 パターン認識とは

パターン認識の成否を決める鍵

  • 識別に有効な特徴を素早く抽出すること

  • 識別規則の学習

  • 学習データを用いて汎化能力を精度よく推定できること

<用語>

特徴抽出

 識別の手がかりとなる特徴量を測定すること。

特徴ベクトル

 抽出されたたくさんの特徴をベクトルの形にまとめたもの

識別規則

 特徴ベクトルを用いて分類を行うための規則

 入力データが所属する正しいクラスに帰属先を探すための規則

学習データ

 入力データとクラスの対応関係を対にした沢山のデータ

汎化能力

 学習データにはなかった未知の入力データについても正しいクラスを識別する能力

1.2 特徴の型

特徴の型

  • 定性的特徴

 非数値データ

  名義尺度 分類のための名前

   名前、住所 etc...

  順序尺度 順序関係を表す。比較はできるが加減算は出来ない

   5段階評価、大中小、優良可

  • 定量的特徴

 数値データ

  間隔尺度 一定の単位で量られた量。原点はあっても「無」ではない

   テストの成績、摂氏・華氏などの温度、年月

  比例尺度 原点が定まっている量。割り算や比例計算が意味を持つ。原点は「無」である

   身長、体重、年齢、絶対温度

 ダミー変数

  定性的な特徴(ほ乳類かどうか etc...)を数値(ほ乳類の場合 1、そうでない場合 0)で符号化すること。

1.3 特徴ベクトル空間と次元の呪い

特徴ベクトル空間

 10 ✖ 10 のドットで文字を表現する場合、100個のドットがあるので、この画像データは100次元の特徴を持つ空間である、と考える。

次元の呪い

 次元(≒特徴量の種類?)が増えれば増えるほど、必要な学習データの数が指数関数的に増えること。

 先ほどの10 ✖ 10 のドットの場合、1つのドットで16色使える場合、情報量が100の16乗(千兆)になる。

超立方体

n次元の各辺が等しい図形のことらしい。

頂点の数と辺の数は以下のとおり導ける。

4次元の立方体の理解 - 大人になってからの再学習 より

■ 頂点の数は2倍ずつ増える

■ 辺の数は1つ前の次元の「辺の数の2倍と頂点の数」を足した数になる。

もとのカタチを新しい次元に平行移動して(辺の数は2倍増える)、対応する頂点間を結ぶため(辺の数は頂点の数だけ増える)。

f:id:kj_man666:20200505135750j:plain

感想

まだ初めの方のため、用語の定義の話が多いので、まだついていける。

超立方体の頂点の数はともかく、辺の数や面の数を計算しようと思うと、その1個前の次元の情報が必要になってくるため、よくわからなかった。。

以上になります、最後までお読みいただきありがとうございました。

GW後半2日目で振り返り

f:id:kj_man666:20200503202255j:plain

stayhome でロクに遊びにも行けませんが、GWも2日目ということで、気持ちがダレないよう、振り返ってみました。

<勉強>

統計的機械学習の数理100問 251ページ中、19ページ

 行列式と偏微分がわかってないので、テキストを見ながらノートにガリガリ書いて理解進め中。

www.kyoritsu-pub.co.jp

・DLGのkaggle勉強会

 取り組んでいるコンペの進捗を共有した。

 と言っても、人のnotebookに書いてコードを整理して理解に努めているだけですが。。

 ちゃんと自分で組めるようになるのはいつになるやら。

www.kaggle.com

data-learning.com

<動画視聴>

・ネットフリックス

 カウボーイビバップを見ました。

 3回目くらいに見返した作品ですが、年齢を重ねて見てみると、ジェットの面倒見の良さが際立つ・・・。

www.cowboy-bebop.net

<ゲーム>

・Fallout クラシックコレクション

 Fallout 歴は4を少しやったことある程度。

 PC だけでプレイできる、ある程度知ってて、かつネタバレは知らなくて面白そうな作品、ということでチョイス。

 PS4 は売り切れで買えず、申し込んだ Switch の抽選にはことごとく外れているので、PC で出来る Steamで Fallout を堪能しようと思います。。

store.steampowered.com

<マンガ>

・サマータイムレンダ

 狭くて浅いやつら、というポッドキャストで知って読み始めたのですが、めちゃくちゃ面白くて一気に9巻まで読み進めてしまいました!

 タイムループ、田舎の孤島、得体のしれない敵との闘い、魅力的なキャラクターと盛りだくさんです。

 後半のタイムループの説明が高度過ぎて、ちょっと私の頭ではついていけなくなりましたが。。

 次の単行本発売が楽しみです!

 こういう作品が好きな方は是非!

www.shonenjump.com

semaasa.net

<雑感>

早寝早起きは継続中。

遊びすぎず、勉強しすぎず、と連休を堪能しております。

連休中で統計的機械学習の数理100問をこなせるかなーと思ってましたが、甘かったようです。

数学の学びなおしもかねてと割り切って、じっくり腰を据えて取り組もうと思います。

以上になります、最後までお読みいただきありがとうございました!

python の melt() でグラフ化しやすいデータに加工する

f:id:kj_man666:20200426103314j:plain

python の melt でグラフ化しやすいデータに加工するテクニックをまとめました。

まずは、グラフ化しにくい DataFrame型のデータを作成します。

import pandas as pd

# データの作成
df = pd.DataFrame(data=[('a',1,2,3,4,5,6,7),('b',8,9,10,11,12,13,14),
                        ('c',15,16,17,18,19,20,21),('d',22,23,24,25,26,27,28),
                        ('e',29,30,31,32,33,34,35),('f',36,37,38,39,40,41,42),
                        ('g',43,44,45,46,47,48,49)])

df.columns = ['category', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']

こんな感じのデータが出力されます。

f:id:kj_man666:20200426102102p:plain

これだとカラムの1つか2つくらいしかグラフに出来ず、Sun(日曜)~Sat(土曜)と時系列にならべることができません。

df.plot("category", "Sun")

f:id:kj_man666:20200426102153p:plain

そこで、melt 関数を使って並べ替えます。

df_m = pd.melt(df, id_vars=['category'], 
              value_vars=['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
              var_name = "Day of the week", value_name = "Num")

f:id:kj_man666:20200426102307p:plain

以降、データが続く・・・

このようにデータを整えると、時系列に並べてグラフ化ができます!

df_m.plot("Day of the week", "Num")

f:id:kj_man666:20200426102351p:plain

以上になります、最後までお読みいただきありがとうございました。

コードはこちら

参考

nekoyukimmm.hatenablog.com

公式ドキュ

pandas.pydata.org

ABL 「乗り越えられないキューバックログの回避」を読んだ

(2020/4/27 修正 コンシューマー、プロデューサーという原文の表現を、消費者、開発者という意味ではなく、本来のキューから情報を受け取る側、キューへ情報を渡す側、という意味に修正しました。)

 輪読会に向けて、Amazon Builder's Library(以下、ABL) を読んだので、簡単にまとめてみました。

 テーマは「乗り越えられないキューバックログの回避」です。

aws.amazon.com

 記事は AWS のシニアプリンシパルエンジニアが書いておりまして、項目は、以下の8つでした。

はじめに 生命を模倣するアルゴリズム

 キューは短ければ短いほど良い。

 前半はバックログにつながる流れを、後半はキューのバックログを適切に処理して蓄積するのを防ぐ方法が解説されている。

 (考察)バックログは後から入ってきたデータで、処理待ちで溜まっているデータのことをさす?

 キューとは、最も基本的なデータ構造の一つで、要素を入ってきた順に一列に並べ、先に入れた要素から順に取り出すという規則で出し入れを行うもの。
 順番を待つ人の行列と同じ仕組みであるため「待ち行列」とも訳される。

e-words.jp

 待ち行列理論(まちぎょうれつりろん 英語: Queueing Theory)とは、顧客がサービスを受けるために行列に並ぶような確率的に挙動するシステムの混雑現象を数理モデルを用いて解析することを目的とした理論である。
 応用数学のオペレーションズ・リサーチにおける分野の一つに数えられる。

 電話交換機や情報ネットワーク、生産システム、空港や病院などの設計や性能評価に応用される。
 性能評価指標としては、待ち行列長・待ち時間・スループットなどが用いられる。
 応用の場では、システムの性能がある設計目標を満たすために必要な設計パラメータを決定する際に、その逆問題を提供できる。

ja.wikipedia.org

キューの二重の性質

 キューを使うと、メッセージが処理されるまで保留されるため、システムの耐久性と可用性は上がるが、一方でレイテンシー増加の要因となる。

 Amazonには、キューを使った非同期システムが多い。

 通信を行う機器間でデータや信号の送信と受信のタイミングを合わせる動作や仕組みを用いずに通信することを非同期通信という。

 ソフトウェア間のデータの送受信などに関して非同期通信という場合は、送信や受信の処理を他の処理から独立して並行に行う「非同期処理による通信」を指すことが多い。

e-words.jp

 (Amazon.comの注文処理、Amazon RDSがEC2 インスタンスをリクエストしDBを設定する流れ、CloudWatchのメトリクスとログの取込システム 等)

 しかし、キューを使うと、可用性を下げてしまう可能性がある。

 処理が止まってもメッセージが届き続け、処理時間がより遅くなる可能性があるからである。

 キューをベースにしたシステムは、バックログがなければ高速に処理できるが、バックログがたまってくると処理を遅延させる要因になる。

キューベースのシステム

  2つの例を挙げる。

 ① AWS Lambda

  AWS Lamda は障害が発生しても処理を完了させるため、永続キューを採用している。

www.youtube.com

 ② AWS IoT Core

  AWS IoT Core はデバイスがデータ受信できるよう待機することでリソースを消費してしまわないよう、非同期システムを採用している。
 データ受信したデバイスがオフラインである可能性もあり、オンラインになったときにデータを受け取れるよう、永続キューを採用している。

 WS IoT Core は、インターネットに接続されたデバイスから、クラウドアプリケーションやその他のデバイスに簡単かつ安全に通信するためのマネージド型クラウドサービスです。

aws.amazon.com

 キューベースのシステムは、永続キューを実装する。

永続キュー属性(-mオプションにpersistentを指定)
 送信側アプリケーションが送信したメッセージは,受信側アプリケーションが受信するまでキューのあるDB上で永続的に管理されます。
 DB障害以外によってメッセージが消滅しないため,通常は永続キュー属性を指定することをお勧めします。

itdoc.hitachi.co.jp

 SQSはメッセージが配信されたかどうかのセマンティクス(正しく動作したかの判断基準)を提供する。
 LambdaやAWS IoT Coreもこれを利用している。
 メッセージ処理が完了してからキューを削除している。

セマンティクス
 プログラミング言語において、ソースコード中で利用されている変数や文が正しく動作するかを判断する基準のこと。
 たとえば、ヌルが定数として定義されている値がアドレス参照のために使われていると、セマンティクスに違反しているとみなして、エラーと判断する。

kotobank.jp

非同期システムの障害

 1時間停止した非同期システムは、停止した間にキュー処理が溜まるため、停止から回復後は、溜まったキュー処理と通常の処理を同時に処理するため、処理の負担が2倍になってしまう。

 特にLambdaのような柔軟な処理を求められるシステムは、さらに負荷が増えて必要な能力が2倍以上になる。

 これが処理能力を超えると、停止中はリクエストをカットする同期システムよりも、非同期システムのほうが回復に必要な時間がかかってしまうことになる。

 したがって、非同期システムでもレイテンシー1秒以下の高い処理能力が求められる。

可用性とレイテンシーの測定

 制作者の可用性は、使用しているシステムのキューの可用性に比例する。
 SQSを使えばSQSの可用性と一致する。

 Amazon Simple Queue Service (SQS) は、完全マネージド型のメッセージキューイングサービスで、マイクロサービス、分散システム、およびサーバーレスアプリケーションの切り離しとスケーリングが可能です。
 SQS では、メッセージ指向ミドルウェアの管理や運用に関連する複雑さやオーバーヘッドを排除できるため、開発者が差別化作業に集中することができます。

aws.amazon.com

(2020/4/27 修正 原文のプロデューサー、コンシューマーという表記から、プロデューサー=開発者、コンシューマー=エンドユーザーかと思ってしまったが、システムのキューへメッセージを渡す側をコンシューマー、システムのキューからメッセージを受け取る側をコンシューマーというそうです)

メッセージを送信するには、プロデューサーというコンポーネントがキューにメッセージを追加します。
コンシューマーという別のコンポーネントがメッセージを受信して処理するまで、メッセージはキューに保存されます。

aws.amazon.com

 エンドユーザーコンシューマー側から見ると、障害が起きると再試行になってしまうため、システムの可用性が実際よりも悪いという印象を抱く場合がある。

(補足:開発者の可用性=スペック通り、エンドユーザーの可用性=ちゃんと使えるかどうか、ということを言いたいのだろうか?)

 再試行中に届いたメッセージは、ドロップされるか デッドレターキューの中に格納される。

(DeepL訳参考)メッセージキューイングにおいて,デッドレターキューは,以下の条件のうち1つ以上を満たすメッセージを格納するためのサービス実装である。

 1.存在しないキューに送信されるメッセージ
 2.長さ制限を超えたキュー
 3.長さ制限を超えたメッセージ
 4.他のキュー交換で拒否されたメッセージ
 5.消費されないために、しきい値のリードカウンタ番号に達するメッセージで、 "バックアウトキュー "と呼ばれることがあります。

 これらのメッセージをもつデッドレターキューのおかげで、開発者が共通のパターンと潜在的なソフトウェアの問題に専念することができます。
 デッドレターキューを組み込んだキューイングシステムには、Amazon Simple Queue Service、Apache ActiveMQ、HornetQ、Microsoft Message Queuing、Microsoft Azure Event Grid and Azure Service Bus、WebSphere MQ、Rabbit MQ、Apache Pulsarなどがあります。

en.wikipedia.org

 ドロップされたメッセージまたはデッドレターキューに格納されたメッセージのレートは、可用性を図るよい指標となるが、問題の検出が遅すぎる場合がある。
 デッドレターキューの容量について警告するのは良い考えだが、デッドレターキューの情報が到着するのが遅いので、問題を検出するために使うには不十分である。

マルチテナント非同期システムのバックログ

  多くの非同期システムはマルチテナントである。

 マルチテナントとは、SaaSやASPサービスなどで、機材やソフトウェア、データベースなどを複数の顧客企業で共有する事業モデル。
 また、システムやソフトウェアが複数の利用者で共有できるような設計・構造になっていること。

e-words.jp

(抜粋)マルチテナント型クラウドサービスの例
AWS
Azure

ec-orange.jp

 マルチテナントの利点は、個別管理が不要であり、運用のオーバーヘッドを節約してリソースを集中させられることである。

 ITの分野では、コンピュータで何らかの処理を行う際に、その処理を行うために必要となる付加的、間接的な処理や手続きのことや、そのために機器やシステムへかかる負荷、余分に費やされる処理時間などのことをオーバーヘッドということが多い。
 通信の分野でも、送りたいデータや信号そのものとは別に付加的に必要となる制御用のデータなどのことや、それを処理、伝送するために余計にかかる負荷や時間のことをオーバーヘッドという。

e-words.jp

 しかし、エンドユーザーは、他のエンドユーザーがどれだけ負荷をかけているかに関わらず、シングルテナントのように、高い可用性とレイテンシーが許容可能な範囲であることを求めてくる。

 SaaS(サース)などのサービスにおいて、顧客企業が一つのシステムを専有する方式。

kotobank.jp

 AWSのサービスは、内部キューを直接公開する代わりに、軽量なAPIと認証システムを実装している。
 APIにより、エンドユーザーの公平性を保つことができる。
 AWSは、顧客の規模に応じて、ある程度の柔軟性を持たせつつ、エンドユーザー個別の制限を設けている。

 制限によって突発的なスパイク(負荷の増加)によるシステムダウンを防ぎ、裏でプロビジョニングを確保する。

 プロビジョニングとは、必要に応じてネットワークやコンピューターの設備などのリソースを提供できるよう予測し、準備しておくことです。供給や設備等の意味を表すプロビジョン(provision)という単語がもととなって派生した言葉です。

www.idcf.jp

 非同期システムの公平性は、同期システムの調整と同じように機能するが、非同期システムは大量のバックログがたまる可能性があるため、同期システムの調整よりも重要である。
 例として、非同期システムに制限がかかっていない状況で、1人のエンドユーザーがトラフィックを大きく増加させ、システム全体のバックログを増加させた場合を考えてみよう。
 オペレータが状況を把握し、問題を対処するのに30分かかり、その間にスケーリングした容量の10倍の量がキューに入れられてしまうと、システムが正常に回復するのに、問題対処のため停止していた時間(30分)の10倍の300分かかる計算となる。
 非同期システムの場合、短時間の突発的なスパイクでも、キューに大量のバックログがたまることで、長時間の停止が発生する可能性があるのである。

 実際のAWSには、Auto Scalingのような防止する仕組みがある。
 また、複数のキューを設定したり、最新のデータが処理されるためエンドユーザーにウケの良い後入後出になるよう設計するとよい。

 AWS Auto Scaling は、安定した予測可能なパフォーマンスを可能な限り低コストで維持するためにアプリケーションをモニタリングし、容量を自動で調整します。

aws.amazon.com

復元力のあるマルチテナント非同期システムを作成するための Amazon の戦略

 マルチテナントの非同期システムを障害に強くするためにAmazonが採用している戦略パターン

① ワークロードを個別のキューに分離する

 各顧客に独自のキューを割り当てる。
 ただしコスパが悪く、エンドユーザーが多いと処理が手間になる。

② シャッフルシャーディング

 1つしかキューがないと障害の原因につながりやすいため、予備として複数のキューを割り当てる。

(手前味噌ですがシャッフルシャーディングの詳細は以下)

megane-man666.hatenablog.com

③ 過剰なトラフィックを別のキューに並べる

 過剰なトラフィックを選り分ける。

④ 古いトラフィックを別のキューに並べる

 古いトラフィックを選り分けることで、新しいメッセージを素早く処理できる。

⑤ 古いメッセージのドロップ

 一部のシステムでは、古いトラフィックを削除する。

⑥ ワークロードごとのスレッド (およびその他のリソース)の制限

 1つのワークロードが割り当てたシェア以上のリソースを使えないよう、システムを設計する。
 処理は遅くなるが、負荷が同じであれば同時に実行できる処理の量が増加する。
 処理能力はリトルの法則で表される。

リトルの法則(Google 翻訳)

 待ち行列理論、数学内の規律確率論、リトルの結果、定理、補題、法律、または式による定理であるジョン・リトル長期平均数のことを述べL Aの顧客の定常システムは、長期平均実効到着率λに顧客がシステムで費やす平均時間Wを掛けたものに等しい。
 代数的に表現される法則は
f:id:kj_man666:20200422203547p:plain
(L:店舗の平均顧客数 λ :単位時間あたりの客数 W:平均滞在時間)
 直感的には簡単に見えますが、「到着プロセスの分布、サービスの分布、サービスの順序など、実質的に何の影響も受けない」ため、驚くべき結果です。

en.wikipedia.org

 ノンブロッキング I/O を使用して処理能力を確保する。

 最も単純なシングルスレッド×ブロッキングIOです。
 店員(スレッド)が1人しかいないので同時に1人のお客さんしか処理できません。

 マルチスレッド×ブロッキングIOです。ApacheなどノンブロッキングIOが登場する前のサーバアプリケーションはこのモデルでした。
 単純にスレッド店員(スレッド)を増やすことで同時に処理可能なお客さんの数が増えました。店員の数を増やせば増やすほど同時に処理可能なお客さんを増やすことができますが、増やすことができるのはレジの数(CPU)までとなります。それ以上の店員がいても基本的には意味がありません。

 ノンブロッキングIOです。店員さんがスキルアップし、お弁当の温め中に次のお客さんの会計を行うことができるようになりました。

takezoe.hatenablog.com

⑦ バックプレッシャーをアップストリームに送信する

  バックプレッシャーはすべてのシステムに向いているわけではない。

 バックプレッシャーとは、半二重接続のネットワーク機器などで用いられるフロー制御方式の一つで、受信側が記憶装置の容量の飽和を防ぐためにわざと送信側の送信動作を妨害・抑止する手法。

e-words.jp

⑧ 遅延キューを使用して後まで作業を先送りにする

 メッセージの配信を待機させれば、システムは最新のデータを処理することができる。

⑨ あまりにも多くの処理中のメッセージを避ける

 デキューに失敗してメッセージが削除されないバグが発生する可能性があるので、この余計なメッセージを別のキューに移動するとよい。

⑩ 処理できないメッセージにデッドレターキューを使用する

 一旦デッドレターキューに格納することで、バグが修正された後にメッセージを再処理することが可能。

⑪ ワークロードごとにポーリングスレッドで追加のバッファーを確保する

 ポーリングスレッドが常にビジーになる場合は、バッファーが足りない可能性があるので、追加のバッファを準備する。

 スレッド(thread)とは、プログラムが処理を実行する単位をプログラマの必要に応じて増やせるものです。

 ポーリング(polling)とは、プログラミングでは定期的に問い合わせをする処理方法のことです。シンプルかつ直感的な処理方式です。

 ポーリングでは、スレッドでの処理が終わったかを、スレッド自身へ定期的に問い合わせます。
 スレッドが終わったと回答したなら、そこで結果を受け取るのです。

engineer-club.jp

⑫ ハートビートの長期メッセージ

 タイムアウトが生じて再試行を続けるときに、連鎖的に発生した電圧ダウンの可能性を考慮してメッセージのハートビートを続行することがある。

 ハートビートとは、ネットワークで接続されたコンピューターやネットワーク機器が、接続が有効であることを確認するために、定期的に送信する信号のことである。

www.weblio.jp

 この場合、負荷が増加してしまい、システムのレイテンシーが可視性タイムアウトのしきい値を超えてしまうと、その行為自体がさらに負荷を発生させるフォーク爆弾になってしまうことがある。

 可視性タイムアウトとは、 SQS のキューに入ったメッセージが処理開始直後に重複して処理されないように、処理中の場合、一時的に他のプロセスからは、メッセージが存在していることを見えないようにする設定です。

dev.classmethod.jp

 Fork爆弾(フォークばくだん)とは、コンピュータシステムへのDoS攻撃の一種で、新たなプロセスを生成するfork機能を使ったものである。

ja.wikipedia.org

⑬ クロスホストデバッグを計画する

  分散システムの障害は複雑すぎる。
 これらのアプローチとしては、以下が挙げられる。

  • キューの深さを定期的に計測する。
  • AWS X-Rayを使って分析及びデバッグを行う。

 開発者は、AWS X-Ray を使用して、本番環境や分散アプリケーション (マイクロサービスアーキテクチャを使用して構築されたアプリケーションなど) を分析およびデバッグできます。
 X-Ray を使用すると、アプリケーションやその基盤となるサービスの実行状況を把握し、パフォーマンスの問題やエラーの根本原因を特定して、トラブルシューティングを行えます。
 AWS X-Ray では、アプリケーション全体で転送されるユーザーリクエストがトレースされます。

aws.amazon.com

  •  複雑なワークフローの非同期システムがある場合は、AWS Step Functionsをつかってワークフローを整理する。

 AWS Step Functions では、AWS の複数のサービスをサーバーレスのワークフローに整理できるため、すばやくアプリケーションをビルドおよび更新できます。

aws.amazon.com

まとめ

  非同期システムは、先入先出の仕組みを取っているため、レイテンシーが重要であるが、その重要性が見過ごされがちである。
 非同期システムの場合は、サービスの復旧に時間がかかるとたまったバックログの処理にさらに膨大な時間がかかり、障害につながる可能性がある。
 非同期システムを構築する場合は、バックログがどのようにたまるかを予測し、様々な手法を取ってこれを最小限に抑える必要がある。

 

 以上になります、最後までお読みいただきありがとうございました。

 

おまけ

 キュー処理をpythonで再現しているサイトを見つけましたので、やってみました。

# キュー処理を実行するためのクラス
class Queue(object):
  def __init__(self):
    self.queue_list = []

  # エンキュー(キューに入れる)処理の関数
  def enqueue(self, value):
    self.queue_list.append(value)

  # デキュー(キューから外す)処理の関数
  def dequeue(self):
    try:
      # 先頭をとりだす
      value = self.queue_list.pop(0)
    except IndexError:
      value = None

    return value

 

queue = Queue()

# a、b、c をそれぞれエンキューする
queue.enqueue("a")
queue.enqueue("b")
queue.enqueue("c")

 

# デキュー1回目。1番最初に入れた a が出力される
print(queue.dequeue())

# デキュー2回目。2番目に入れた b が出力される
print(queue.dequeue())

# デキュー3回目。3番目に入れた c が出力される
print(queue.dequeue())

# デキュー4回目。全てデキュー済みなため、何も出力されない(None)
print(queue.dequeue())

 

出力結果

f:id:kj_man666:20200425162730p:plain 

(参考)コードはこちら (python3)

元ネタ (ただし python2)

qiita.com

連続する数字と記号/文字の要素が入った配列を楽に作りたい

f:id:kj_man666:20200423224735j:plain python の for 文の内包表現と、フォーマット済み文字列を組み合わせたテクニックです。

No.1、No.2、No.3 ... という文字+連続する数字が入った配列を簡潔な記述で作りたい場合

list = [f"No.{num}" for num in range(1, 10)]
list

f:id:kj_man666:20200423223949p:plain

これを応用して、トランプのカード(スート+数字)を簡潔な記述で作ることができます。

cards = [f"{suit}{num}" for suit in ("♠", "♡", "♢", "♣") for num in range(1, 14)]
cards

f:id:kj_man666:20200423224002p:plain (以下続く・・・)

以上になります、最後までお読みいただきありがとうございました。

コードはこちら

参考

for の内包表現とは

list = [i for i in range(1,10)]

とすることで、[1,2,3...9] という配列を簡潔に作ることができる。

note.nkmk.me

フォーマット済み文字列は、

"{}".format() とすることで、{}内にformat()内の文字列を入れることができる。

f"{}"と簡潔に書くこともできる。

www.javadrive.jp

pprint() でリストや辞書を整形して出力するテクニック

f:id:kj_man666:20200419184019j:plain

小ネタですが、pprint() でリストや辞書を整形して出力することができます。

まずは表示がややこしい辞書型のデータを作成します。

# 辞書型のデータの作成
dic = {
            'C134':{"price":30,"sales":"1000","profit":200 ,"alist":[110,20,30 ,50]}, 
            'C623':{"price":80,"sales":"100" ,"profit":6   ,"alist":[100,10,30 ,50]},
            'C430':{"price":70,"sales":"5000","profit":1000,"alist":[160,11,120,6]},
            'C115':{"price":10,"sales":"2400","profit":40  ,"alist":[80 , 1,10 ,6]}
        }

まずは、データ名をそのまま打ち込んで出力したパターン。

dic

f:id:kj_man666:20200419184923p:plain

これはこれでキレイに表示されていますが、この後にコードを入力すると、データの中身は表示されません。

また、インデントが若干見づらいところがあります。

次に print() を使った場合。

print(dic)

f:id:kj_man666:20200419184909p:plain

ぎっしり表示されてしまうため、かなり見づらいですね。

最後に pprint() を使う場合。

import pprint() する必要があります。

import pprint
pprint.pprint(dic)

f:id:kj_man666:20200419184854p:plain

インデントもキレイにされ、かなり見やすく表示されます。

難点を言うと、昇順で並び変えられてしまっているところですね・・・。

パラメーターが増えてちょっとだけ手間ですが、バージョン 3.8 以降は、sort_dicts = False を追加することでソートせずに出力することが可能です。

pprint.pprint(dic, sort_dicts = False)

f:id:kj_man666:20200419220144p:plain

以上になります、最後までお読みいただきありがとうございました。

(参考) pprint() の詳細 note.nkmk.me

複雑なdict型を拝借したサイト qiita.com

pprint() のドキュメント docs.python.org

ブログ内のコード github.com 20200419_pprint.ipynb

ABL 「シャッフルシャーディングを使ったワークロードの分離」を読んだ

f:id:kj_man666:20200418083017j:plain

 輪読会の発表に向けて、Amazon Builder's Library(以下、ABL) を読んだので、簡単にまとめてみました。

 テーマは「シャッフルシャーディングを使ったワークロードの分離」です。

aws.amazon.com

 記事は、Amazon Web Service のシニアプリンシパルエンジニアの方が書いておりまして、項目は、以下の6つでした。

はじめに

DNS ホスティングの対応開始

DDoS 攻撃への対処

シャッフルシャーディングとは?

Amazon Route 53 とシャッフルシャーディング

まとめ

  それでは内容について触れていきたいと思います。

 

はじめに

 Amazon Route 53 立ち上がり時期の話。

Amazon Route 53 は、可用性と拡張性に優れたクラウドのドメインネームシステム (DNS) ウェブサービスです。
Amazon Route 53 は、www.example.com のような名前を、コンピュータが互いに接続するための数字の IP アドレス (192.0.2.1 など) に変換するサービスで、開発者や企業がエンドユーザーをインターネットアプリケーションにルーティングする、きわめて信頼性が高く、コスト効率の良い方法となるよう設計されています。

aws.amazon.com

DNS ホスティングの対応開始

 ドメイン名を自由に変えるためには、利用者のドメインを、実際にホスティングする必要がある。

ホスティングの定義
 ホスティングとは、一言で表すと「サーバを借りること」です。
レンタルサーバと呼ばれることもあります。
 もう少し詳しく表すと、インターネットサービスプロバイダなどが顧客にサーバを貸し付けて、そこにメールサービスやウェブサービスを預けておくことを言います。

boxil.jp

 DNS に問題が発生すれば、サービス全体がオフラインになる可能性がある。
 DNSホスティングを行えるようにするのは難しい取り組みであったが、Amazonはドメイン名を変えたいという顧客の需要に応えようとした。

 

DDoS 攻撃への対処

 いちばん難しい課題は、DDoS(distributed denial of service)攻撃への対応である。

 DoS攻撃(Denial of Service attack)とは、サイバーの攻撃の1つであり、攻撃目標であるサイトやサーバに対して大量のデータを送り付けることで行われる攻撃です。
 受信側はトラフィックが異常に増大するので、負荷に耐えられなくなったサーバやサイトがダウンしてしまいます。

cybersecurity-jp.com

 

 DNS は UDP プロトコルを使っているためリクエストが偽装されやすい。

UDP(User Datagram Protocol)
 再送制御などを行わず「送りっぱなし」にする仕組みなので、TCPほど信頼性が高くはないですが、そのぶん速いので、高速性やリアルタイム性を求める通信に使用されるプロトコルです。
 TCPがコネクション型と言われるのに対して、UDPはコネクションレス型プロトコルと言われます。

kansiho.hatenablog.com

 DNSがUDPを使うのはなぜですか?

 DNSにおける名前解決では、やりとりされるデータが小さいことから原則として問い合わせ・応答ともに1パケットのUDPで行えるように設計されています。
 これはTCPに比べてUDPはプロトコルオーバヘッド※1が小さいという利点があるからです。

kansiho.hatenablog.com

www.atmarkit.co.jp

 にも関わらずDNSは重要なインフラであるため、ハッカーの攻撃の対象になりやすい。

 ドメインに対しては毎日数千のDDoS攻撃が仕掛けられている。

  対抗策として、サーバーの容量を増やすことが考えられるが、攻撃側に比べてコストがかかりすぎるため、現実的には難しい。

 そこでAmazon Route 53 が生み出したのが、シャッフルシャーディングである。

シャッフルシャーディングとは?

シャード時間
 シャードとは、Amazon Kinesis データストリームの基本的なスループットの単位です。

aws.amazon.com

 仮想のシャードを使って負荷を分散させる、シャッフルシャーディングを使うことで、被害の範囲を抑えることができる。

 シャッフルシャーディング – シャッフルシャーディングは、データの水平パーティションを別々のデータベースサーバーに分散して負荷を分散し、冗長性を提供するデータベースシャーディングの概念に似ています。
 同様に、Amazon Route 53はシャッフルシャーディングを使用して多数のPoP上でDNS要求を分散し、アプリケーションに複数のパスとルートを提供します。

stay-ko.be

Amazon Route 53 とシャッフルシャーディング

 そして、攻撃されたユーザーを特定し、攻撃対応用のスペースに隔離する。
 DDoS攻撃に対応するためのサービス、AWS Shield もある。

 AWS Shield はマネージド型の分散サービス妨害 (DDoS) に対する保護サービスで、AWS で実行しているアプリケーションを保護します。

aws.amazon.com

 

まとめ

 改良により、複数のレイヤーでアイテムをシャードすることで、最終ユーザー(B(AWS) to B(AWS契約者) to C の C のこと?)も隔離できるようになった。
  シャッフルシャーディングは通常追加コスト無しで導入できる。

 

参考

 

 以上になります、最後までお読みいただきありがとうございました。