/// BANGBOO BLOG ///

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28


June 2024 List
BT on Jun 21, 2024 11:00 PM
スト6 on Jun 19, 2024 12:36 AM
Cloud SQL on Jun 02, 2024 1:06 PM
GCP hands-off 3 on Jun 01, 2024 3:24 PM

June 21, 2024

BT
あそびはここで終わりにしようぜ~

Big Table
Cloud Bigtableを触ってみよう - Uzabase for Engineers
でっかいテーブル、読み書き低レイテンシー、RDBは負荷高いときにレプ数位でスケールが難しいがBTはするので正規化せずに単一テーブルにしておく感じ
row keyが主役
データを追加するのに3パターンある(行追加、列追加、セル追加)
 行に複数カラムファミリーにカラムが幾つか入れられるのでKVSだが結局Where句みたいに使う?
  行キー「企業ID#日付」,COLUMN FAMILY「STOCK PRICE」,COLUMN「HI PRICE」「LO PRICE」に対してJSONデータを入れておく等 
  時間はバージョン管理として持っている
 複雑な条件は無理でデータを事前整理して入れておき、JSONカラムを使ったりで一行にまとめスキャンを一発で済ます等で高スループットのみ
  Google検索のようにキーワードを入れると、検索結果が数多く一瞬で返る等
  複雑な条件はDataprocを使うらしい

Big table構成
Bigtableを徹底解説! - G-gen Tech Blog
インスタンスの中に一つ以上のクラスタ(ゾーン別に設定しレプリケーション)> 各クラスタには1つ以上の同数のノード 
 クラスタに table > 複数Column family > 複数Column > セル
bigtable_app_profilesで転送クラスタ先の設定する(単一行トランザクション設定を含む)
 -マルチクラスタ(自動フェイルオーバ、単一行transaction不可でレプリケーションによる不整合あり) 
 -シングルクラスタ(手動フェイルオーバ、一行transaction) 
デフォルトをマルチにして、通常のクラスタ転送をシングル、問題があるときだけアプリで判定しマルチに行く
Bigtableで複数クラスタ構成におけるデータ整合性の保証 - Carpe Diem (hatenablog.com)

スキーマ:
 テーブル
 行キー(row key)
 カラムファミリー(カページコレクションポリシーを含む)
 カラム
更新したデータはタイムスタンプによりセル内で保存される
 解消するにはガベージコレクション
  期限切れ値、バージョン数で設定する

仕様:
KVS、行指向の行単位でスキャン
各テーブルのインデックス (行キー)は1つのみで一意である必要がある
行は、行キーの辞書順に並べ替えられます。
列は、列ファミリー別にグループ化され、列ファミリー内で辞書順に並べ替えられます
列ファミリーは特定の順序では保存されません
集計列ファミリーには集計セルが含まれます
行レベルでアトミック (複数行だと知らんという意)
 アトミック性:トランザクション整合性がある(一部の操作だけ実行した状態とならずに)
特定の行にread/writeが集中するより分散が良い
Bigtable のテーブルはスバース、空白行での消費はない

cbt CLI の概要  |  Bigtable Documentation  |  Google Cloud
cbt リファレンス  |  Bigtable Documentation  |  Google Cloud
gcloud components update
gcloud components install cbt
(-/cbtrcに以下記載すれば-projectと-instance はデフォルト値で省略できる)
cd ~
echo project unco > ~/.cbtrc
echo instance = chinco >> ~/.cbtrc
cbt -project unco listinstances
cbt -instance chinco listclusters
cbt -project unco -instance chinco ls | grep kuso-t
 テーブル名取得
cht -project unco -instance chinco ls kuso-table
 カラムファミリやポリシー等取得
cbt -project unco -instance chinco deletefamily kuso-table shikko-family
cbt -project unco -instance chinco deletetable kuso-table
 テーブルを消せばカラムファミリも削除になる

Posted by funa : 11:00 PM | Web | Comment (0) | Trackback (0)


June 19, 2024

スト6

///ストートファイター6

隠しシステムを覚えないといけないが膨大にある感じ、練習をして数Fの誤差で手癖を付けないと、、、→いかに反射神経で早く返せるかゲー、アスリートっぽいな、考えると駄目で目で直接に手が動く感じで→低遅延ゲームモードのあるTV欲しい?
 - リフレッシュレート:144Hz以上
 - 応答速度:1ms以下
モダンタイプという簡易操作法がある:クラシックタイプよりも出せる技が少ない、必殺技が強SAに限定され中SA・弱SAが出せない、ダメージが80%に減少してしまうといったデメリット→純正コントローラの時はモダン?、ホリファイティングコマンダーOCTA買ってクラシックだな

【モダン】
通常攻撃は弱□・中×・強〇
投げ □+×(あるいはL2)
ダウン時にボタン2つで後方受け身

必殺技は必殺技ボタン△
スーパーアーツは強〇+必殺技ボタン△(オーバードライブ:EX技)
アシストボタンR2を押しながら弱/中/強の連打でコンボ技のアシストコンボ

ドライブインパクト L1(相手の攻撃を受けつつもカウンター:セビアタ)
 ドライブリハーサル ガード(あるいはR1) > L1+→(防御中の硬直をキャンセルして反撃)

ドライブパリィ R1(防御しドライブゲージを回復:ブロッキング)
 パリティドライブラッシュ(ドライブパリティの構えからキャンセルしてダッシュ)
  R1>→→ 1ゲージ消費
  →>→+R1 の方がやり易い
キャンセルドライブラッシュ (any+→:同時押し)(R1+→:同時押し)(技当ててダッシュ:ガードキャンセル)
 攻撃のままR1オシッパにして前前
 攻撃キャンセルなので3ゲージ消費

※ドライブラッシュの利点
ガード時とヒット時の相手の仰け反りフレームが4F増加し有利フレームが伸びて、通常時は確定反撃を取られてしまう技が安全に使えるようになったり、通常時は繋がらない技が繋がるようになる、小パンから投げができたり。+4Fということ。

※ドライブゲージ(前に攻めていると良いが、後ろ向きで防御中心だと減るシステムと言える)
消費:相手の攻撃を被弾(ガードでも)
回復:前歩き、時間(ただジャンプ中は回復が遅い)、相手に攻撃を当てる(ガードでも)、ドライブパリティで受ける

【クラシック】
投げ 弱P+弱K
ドライブインパクト 強P+強K
ドライブパリィ 中P+中K
パリティドライブラッシュ 中P+中K+→→、→>→+中P+中K
 起き上がりや硬直開けは前者、中2つ押しながら横を連打しとく
 通常は後者がいい、PKが遅くなってパリティが出やすいが、詳しくは:
  N>→>中PK押しっぱなし>→ が良いと思う、↙防御から→が↘になりがち
キャンセルドライブラッシュ キャンセル可能技>(N or →)+中P+中K
 ↙中Kキャンセル>N>中P+中Kがいい(人差し指の第一関節で中K>離して>腹で中P)

スト6対戦のセオリー - ストリートファイター6初心者wiki | スト6初心者wiki - atwiki(アットウィキ)
【ストリートファイター6】マスターになるための”必須テクニック” 10選 (youtube.com)
有利フレームがあれば 打撃か投げ の2択ができる
 1/60秒=1フレーム=0.0166s、6Fが0.1s
 反射は0.2秒(12F)、限界は0.1秒(6F)くらい、インパクト返し0.43秒(26F)でも辛いが
遅らせグラップ
 打撃防御と投げ抜けの両方の防御ができる ←>弱P+弱K
  起き上がりにガードをしながら、少し待ってから投げを入力
シミ―
 有利フレームで投げ間合いから後ろ歩き、遅らせグラップの投げ空振りを誘う
  投げ空振りだとパニッシュカウンターとなり高火力コンボに行ける
有利フレームの選択肢
 攻撃側:投げか打撃かシミ―、起き攻めは投げが強いが遅らせグラップが来る>その場合垂直ジャンプ
 防御側:遅らせグラップか防御かOD無敵技、他はパリティ/バクステ/バックジャンプ
画面端
 攻撃側:ドライブインパクト強い、コンボ繋がる、投げ2回
 防御側:バクステ反撃、ジャストパリィ後ろ投げ
ファジー
 防御しながら相手の攻撃のタイミングで攻撃ボタン、小P入れとく?
  発生の早い攻撃には防御、遅い技には割り込み攻撃ができる
安全飛び
 ダウンした相手にガード入力をしながらジャンプ攻撃
  発生5F以上の対空無敵技に着地後にガードが間に合う
   対空しない相手には着地後に下段技からつなげる、あるいは着地後に投げ
仕込み
 通常技+必殺技を仕込んで入力しておくと、当たった時だけ必殺技が繋がる
  必殺技は早めに入力、遅いと普通に必殺技がでてしまう
ラッシュ仕込み
 中か強>→パリィ/Nパリィの入力しておくと、当たった時だけキャンセルラッシュになる、中距離で仕込んでおく
  逆に弱>→パリィ/Nパリィなら当たらずともキャンセルラッシュになる

インパクト返し
 26F=0.43s内。音を聞きドライブインパクトで返す、他には投げる/パリィ/無敵技/3発当てる/アーマブレイク属性
 強を振り回すとDI返せない、DI返せる技振りをしておく
連続ガード
 有利Fが続き相手が黄色マスで続くヤツ
  ドライブリバーサルだけやり返せる
ヒット確認
 キャラを見るより体力ゲージが減るかで確認できる
  キャンセルラッシュでヒットしなければ弱で防御に回る等の
安全弾
 弱波動拳+対空は距離があれば安全
  防御側はジャストパリィで有利F伸びる+ジャンプ攻撃で対応できる
ドライブリバーサル複合入力
 ↗中P+強P+強Kでガード時はドライブリバーサル、相手空振りならOD技??
パリィでSA入力
 ゲージがあればSAだが、なければパリィ??
省略入力
 ↘↓↘Pでも昇竜拳が出る、しゃがみながら昇竜なので対空有利
バーンアウト
 ゲージが空、パリティできない、ガード硬直+4Fで反撃ムズイ、必殺技で体力削られる、壁やられでスタン
  回復:20s位、ガード/前歩きで早まる、ジャンプで遅くなる
アピール
 全6PKボタン(+N、前、後、キャラにより下)??
  OPTIONボタンメニュー➡︎OPTION➡︎CONTROL➡︎設定変更>LS/RS/タッチバッドが割り当て
トレーニング
 赤は通常技キャンセル可能、青は必殺技をキャンセルしSAに行ける
 R3:キャラを変えて準備>レコードの記録開始>レコード記録停止
 L3:再生開始
入力
 現技が出ているときに次の技ボタンを押す、次の次(の技のボタン)は入れられない(レバー入力はできる)


Ken
ケン コマンドリスト|STREET FIGHTER 6(ストリートファイター6)|CAPCOM
ストリートファイター6 今さら聞けないケンの実用性の高いコンボ(中~上級編)|SUGAKNEE/すがにぃ (note.com)
【スト6】勝てるようになる『ケンの使い方』を解説!初心者におすすめの強い技や立ち回り、コンボ、起き攻めを紹介します!【STREET FIGHTER 6】【ストリートファイター6】 (youtube.com)
【5分下さい】ケンで“実戦向け”コンボを9個に絞って紹介します【スト6】 (youtube.com)
【スト6】ケン 最強コンボ集【プロ解説付き】 (youtube.com)
スト6 ケン とりあえずこれを覚えれば戦えるコンボ - YouTube

Octaポジション:基本は人差し指で弱、中指で中、薬指で強。
  →繋がり必要なら:人差し指で中K→中指で大P、人差し指で中P→中指で大Pのタゲコンなど、人差し指を中にズラス
 人差し指範囲:弱ボタン2つの投げ
 中指範囲:中ボタン2つのパリティ
 薬指範囲:強
  →ドライブインパクトはLボタンにアサイン
パンパンいわせて強めで叩く(キッチリ2つ押せる、フレーム間隔の手癖化)

顎撥二連 中P>強P
SA(レバー2回)、SA3は体力が25%以下ならクリティカルアーツ(CA)になる
 SA1 龍尾烈脚 ↖↖K
 SA2 疾風迅雷脚 ↗↗K
 SA3 神龍烈破 ZZP
龍尾脚 ZK
迅雷脚 ↓↘→K
 風鎌蹴り 中迅雷>派生弱K あばれ潰し
 轟雷落とし 中迅雷>派生中K 中段
奮迅脚 KK
 奮迅昇竜 KK>派生ZP
 奮迅竜巻 KK>派生↖K
 奮迅竜尾 KK>派生ZK(入れ替え)
OD(ボタン2つ)
 OD波動拳 ↗PP
 OD竜巻旋風脚 ↖KK
 OD昇龍拳 ZPP
 OD龍尾脚 ZKK
 OD迅雷脚 ↗KK >派生K >→K

///コンボ
(中P>強P)顎撥2連>(間KK>↖K)奮迅竜巻(間を多めがいい、↖が不完全>ゆっくり目で、最後←押しっぱが良さそう)
顎撥2連>(間KK>ZK)奮迅竜尾脚>昇竜(間を少な目がいい)
強P>OD波動>SA 4400

///反射
何か技がヒット or ラッシュ>顎撥二連>奮迅竜巻 or 大昇竜
  強P or ↓中K>中P+中K>中P>強P>KK>↙K
強P>キャンセルラッシュ
↓中K>弱竜巻>中昇竜 2500:竜巻早く入力
パニッシュカウンター強K>ラッシュ>強P

///基本
波動拳からの対空昇竜、対空は弱昇竜(読みで事前にレバーは入れて置き、来たらPで)
 防御から昇竜の場合はレバーの手の移動距離が長いので反射神経+大げさにレバーを動かす
 弱波動をラッシュで追いかけ攻撃
↓中K>迅雷>派生弱Kか中K(ゲージ回復)
後ろ前歩きでチョロチョロ間合い取り>読み合い(置き/差し/差し返し):長距離強K/強P/中↓K/弱
 リーチが長い技は遅い強、早い技は弱
  しゃがみ防御から迅雷脚は入れやすいし、長距離+派生で使える
  しゃがみ中Kキャンセル>ラッシュか波動か弱竜巻+中昇竜
相手の硬直にカウンターコンボ
中距離でジャスパ、ドライブインパクト
起き攻め
 ラッシュ投げ
 (屈)小Px2>大昇竜 屈小Pヒット確認練習

 屈大P>迅雷>強派生>弱昇竜
 顎撥二連>奮迅竜尾脚>昇竜

Ryu
中下:足払い と 強前:まわしげり のリーチ長いやつ
中前:中段鎖骨割り2発(立ちガードが必要なので良き技となる)
強後:かかとおとし2発

スト6リュウ体験版モダンコンボとか雑感まとめ|アズサキチャンネル【東和正/戸崎時貞】 (note.com)
【スト6体験版】モダン リュウ コンボまとめ in Demoバージョン【Modern Ryu】 - YouTube
【スト6(OBT)】必要十分!リュウ実用コンボ(モダンTYPE)【RYU basic combo】 - YouTube
【スト6】知らないと損!意外と知らないスト6豆知識集!【テクニック】 - YouTube
【初心者向け】全キャラの強技や強連携の対策教えます!【スト6】 - YouTube

===========
内臓と外付けをSSD化
実はカンタン!PS4のSSD化 | 株式会社アスク (ask-corp.jp)
PS4を外付けSSDで高速化させる方法を解説。内蔵HDD換装より手軽にできる! - 価格.comマガジン (kakakumag.com)
PS4®の内蔵ドライブをSSDに換装して高速化しよう! -エレコム (elecom.co.jp)

Posted by funa : 12:36 AM | Column | Comment (0) | Trackback (0)


June 2, 2024

Cloud SQL
■Cloud SQL Python Connector (Cloud SQL language Connector)
CloudSQL auth proxyのバイナリインストールでないやり方
Cloud SQL Python Connector自体は暗号化しないが、内部IPならサーバレスVPCコネクタで暗号化された通信が使え安全になっている。外部IPアドレスの場合はCloud SQL Auth Proxyで通信を暗号化。
Cloud SQL 言語コネクタの概要  |  Cloud SQL for MySQL  |  Google Cloud
GitHub - GoogleCloudPlatform/cloud-sql-python-connector: A Python library for connecting securely to your Cloud SQL instances.

事前必要(pip install>requirements.txt)
Flask==3.0.3
gunicorn==22.0.0
Werkzeug==3.0.3
google-cloud-bigquery==3.25.0
google-cloud-logging==3.11.1
google-cloud-secret-manager==2.20.2
google-api-python-client==2.141.0
google-auth-httplib2==0.2.0
google-auth-oauthlib==1.2.1
websocket-client==1.8.0
google-cloud-resource-manager==1.12.5
Flask-WTF==1.2.1
cloud-sql-python-connector==1.16.0
pymysql==1.0.3

from flask import Flask, jsonify
from google.cloud.sql.connector import Connector
from google.cloud import secretmanager
import pymysql

# 環境変数の定義
PW_NAME = "sql-pw"
PROJECT_NUM = "1234567890"
DB_INSTANCE = "prj:asia-northeast1:db_instance"
DB_USER = "db-user"
DB_NAME = "db001"

# Secret Manager からパスワードを取得する関数
def get_pw(pw_name, project_num):
    client = secretmanager.SecretManagerServiceClient()
    resource_name = f"projects/{project_num}/secrets/{pw_name}/versions/latest"
    res = client.access_secret_version(name=resource_name)
    credentials = res.payload.data.decode("utf-8")
    return credentials

# Cloud SQL接続
def sql_getconn(connector):
    pw = get_pw(PW_NAME, PROJECT_NUM)
    conn = connector.connect(
        DB_INSTANCE,
        "pymysql",
        user=DB_USER,
        password=pw,
        db=DB_NAME,
        ip_type="private",
    )
    return conn

app = Flask(__name__)

@app.route('/test', methods=['GET'])
def get_table_data():
    try:
        connector = Connector()
        conn = sql_getconn(connector)
        cursor = conn.cursor()

        # SQLを実行して結果を取得
        cursor.execute("SELECT no, name, targetDate FROM test")
        rows = cursor.fetchall()

        # 結果をJSON形式に変換
        result = [
            {
                "no": row[0],
                "name": row[1],
                "targetDate": row[2].strftime("%Y-%m-%d %H:%M:%S") if row[2] else None
            }
            for row in rows
        ]

        cursor.close()
        conn.close()
        return jsonify(result), 200

    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

=============
# 追加オプションを使った接続も可
    connector = Connector(
        ip_type="public",  # "private" または "psc" も使用可能
        enable_iam_auth=False,
        timeout=30,
        credentials=None,  # 必要ならGoogle認証情報を渡す
        refresh_strategy="lazy",  # "lazy" または "background"
    )

#トランザクション
    try:
        conn = sql_getconn(connector)
        conn.autocommit = False  # トランザクション開始、あるいは conn.begin()
        cursor = conn.cursor()
        # 挿入するデータを準備
        new_data = [
            {"no": 4, "name": "新しい名前4", "targetDate": "2024-05-01"},
            {"no": 5, "name": "新しい名前5", "targetDate": "2024-05-02"},
        ]
        # INSERT文を構築して実行
        for data in new_data:
            sql = "INSERT INTO test (no, name, targetDate) VALUES (%s, %s, %s)"
            values = (data["no"], data["name"], data["targetDate"])
            cursor.execute(sql, values)
        conn.commit()  # トランザクションをコミット
        print("Data inserted successfully.")
    except Exception as e:
        conn.rollback()  # エラーが発生した場合はロールバック
        print(f"Transaction rolled back due to an error: {e}")
    finally:
        cursor.close()
        conn.close()

#カーソル
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
 params: dict形式で取得#[{'no': 1, 'name': 'Alice',...}, ...]
cursor = conn.cursor(cursor=pymysql.cursors.SSCursor)
 大量のデータを効率的に取得するためにストリーミングで結果を処理
cursor.execute(query, params=None)
 cursor.execute("SELECT * FROM test WHERE no = %s", (1,))
 params: プレースホルダーに対応する値のタブルまたはリスト
cursor.executemany(query, param list)
 cursor.executemany("INSERT INTO test (no, name) VALUES (%s, %s)", [(1, 'Alice'), (2, 'Bob')])
 param list:繰り返し実行するパラメータのリストまたはタブルのリスト
cursor.fetchone()
 row = cursor.fetchone()
 #結果があれば (1, 'Alice', "2025-01-01") のような形式で1行のみ取得
cursor.rowcount
 print(cursor.rowcount) #影響を受けた行数を返す

■接続検証用コンテナをビルド (内部IPを使うrun用)
gcloud builds submit --tag asia-northeast1-docker.pkg.dev/prj/artifact_reg_name/app_name

■IAM?
Cloud SQL設定にCloud SQL 管理者 (roles/cloudsql.admin)、Cloud SQL インスタンス ユーザー (roles/cloudsql.instanceUser)等のIAMが要る?
IAMユーザならいる、ローカルUserなら不要と思われる、ローカルでもCloud SQL Client (roles/cloudsql.client)等は要る

■Cloud SQL MySQL設定
【開発環境】db_instance01
Enterprise / Sandbox / AsiaNorthEast1 (Tokyo) / Single zone
MySQL ver 8.4
Shared core/1cpu 0.6GB/HDD/10GB(auto increase)
PrivateIP/設定にnwが必要(下記)/Enable private path
Auto daily backup 7days (1-5AM) / Enable point-in-time recovery
Week1 sun 0-1am/Enable query insights
root PW: 69696969
【本番環境】
Enterprise plus? キャッシュ使う?
※CloudSQLはTFファイルに記載がなくてもTFステートファイルにPWを含めてしまうためTF化しない

- NW: projects/prj/global/networks/sql-vpc-nw
- Connection name: prj:asia-northeast1 db_instance01

ユーザの作成 sql-user/82828282
 PWをコードに入れない、シクレMgrに保存

■MySQL
utf8mb4_ja_0900_as_ci_ksを使う?
_ai... アクセントを区別しない (Accent Insensitive)
_as... アクセントを区別する (Accent Sensitive)
_ci... 大文字・小文字を区別しない (Case Insensitive)
_cs... 大文字・小文字を区別する (Case Sensitive)
_ks... カナを区別する (Kana Sensitive)
_bin... バイナリ

utf8mb4_unicode_ciでは"ア”と“あ”は同じものとして扱われる
utf8mb4_ja_0900_as_ci_ks では"ア"≠”あ”となりカタカナとひらがなを明確に区別できる
utf8mb4_ja_0900_as_ci_ks ならふりがなを使った並び替えで有効
日本語のデータがメインで検索やソートでひらがな・カタカナ・濁点の区別が必要なら utf8mb4_ja_0900_as_ci_ks が適
日本語と英語を混ぜたデータや広く互換性を持たせたいなら utf8mb4_unicode_ci の方が無難


インデックスをどのカラムに作ればいいか迷った時の3つの設計方針 #DB - Qiita
テーブルレコード数が1万件以上
全体のレコード数の5%程度に絞り込めるカーディナリティ高さ
WHERE句の選択条件、または結合条件
主キーおよびユニークの列には作成が不要
インデックスは更新性能を劣化させる


データベースとテーブルの作成
CREATE DATABASE db;
USE db;
CREATE TABLE test (
    no INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(8) NOT NULL,
    targetDate TIMESTAMP NOT NULL,
    PRIMARY KEY (no),
    INDEX index_name (name),
    INDEX index_targetDate (targetDate)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_ja_0900_as_ci_ks;

ENUM型は選択肢で早いがALTERが面倒なのでvarcharaにする
inquiry_type ENUM('bq', 'pii') NOT NULL
inquiry_type VARCHAR(255) NOT NULL,

VARCHAR(255) (よく使われる最大サイズ)
VARCHAR(1024) (長めの文字列)
VARCHAR(4096) (長文向け)
長いテキストを扱うならTEXT型
InnoDB の1行の最大サイズは約8KB (8126/バイト)
長さは?メールは255で良い

サンプルデータ
INSERT INTO `table` (`name`, `date`) VALUES ('aaa', '2002-02-23');

ORMapperは面倒なのでSQLを使う
ORM Quick Start — SQLAlchemy 2.0 Documentation
【SQLAlchemy】Generic Typesと各種DBの型 対応表
SQLAlchemyでのテーブル定義 #Python - Qiita

■データベースフラグ
confが直接変更できなためフラグとしてパラメータを渡せる
 Cloud SQL studio (コンソールでMySQLが使える)
  MySQLクライアントを使いたいならAuth proxyが必要
 HA構成だとフェールオーバーやリードレプリカ等が使える

■NW
Cloud SQLを徹底解説! - G-gen Tech Blog
Cloud SQLが内部IPだとサーバレスVPCコネクタ、or 外部IPならSQL + auth proxy
内部IPで良いのでVPCを作る、CloudSQLを内部IPで作る
サーバレスVPCアクセスコネクタを作る
 vpc: sql-vpc-nw, subnet: sql-vpc-subnet 192.168.77.0/24
  Gateway 192.168.77.1, Private Google Access On
  sql-vpc-nw-ip-range 192.168.78.0/24 on cloudSQL
  run-serverless-vpc-ac 192.168.79.0/28 on Run
ファイアウォールルールでポート (デフォルトで3306など) を開放
Cloud Run のNW設定で、サーバーレス VPCコネクタを選択、ルートオプションとしてすべてのトラフィックを VPC コネクタ経由で送信を選択
CloudSQLを30分程度掛けて起動、接続>接続テスト

VPC(例: 10.0.0.0/16)
サブネット(Cloud SQL 用): 10.10.0.0/24(例: us-central1、VPC内)
サブネット(VPCコネクタ用): 10.8.0.0/28(RunからVPCへ通信用、VPC外)
 VPC コネクタのサブネットは 10.8.0.0/28 のような小さな範囲を使用、VPC外だがrun自体がVPC外だから?
 VPC コネクタはリージョン単位なので、Cloud Run と Cloud SQL を同じリージョンに配置するのが望ましい
Google Cloudの内部NW設計によりVPC内の異なるサブネット間でも通信可能
 VPC内なら異なるリージョンのサブネットでもOK(VPC自体には範囲を設定なしでサブネットでIPが被らなければOKかと
 追加の設定なしで、例えば us-central1 の VM から asia-northeast1 の Cloud SQLに直接アクセス可

外部IPの場合:
アプリがrunならサイドカーコンテナとしてAuth Proxyを追加できる
 サイドカーは同Pod内なのでループバックアドレス127.0.0.1あるいはlocalhost:5432 (Auth Proxy起動時に指定したポート) に通信しCloudSQLに接続する
GCEにDLしてAuth proxyインストールでもいい
 アプリのコネクタはAuth Proxy動いているGCEのIP:ポート番号を指定に通信しCloudSQLに接続する
 FWでポートも開けること

■run サービスアカウント
run-sql@prj.iam.gserviceaccount.com に必要な権限
 Cloud SQL Client (roles/cloudsql.client)
 Run Invoker (roles/run.invoker)
 Compute Network User (roles/compute.networkUser) -VPCコネクタを使用する

runを建てるが、InternalIPのため同プロジェクト同VPCのGCE を作成し移動してCURLでテスト
curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" "https://run-sql-test-1212124.asia-northeast1.run.app/test"

■MySQLでUUIDを使うか、連番を使うか? > ULIDを使う
UUIDは連番に対し
 セキュリティ上より安全、サーバが異なってもユニーク
 パフォーマンスが悪い (UUIDをプライマリキーにすると速度が落ちる場合がある)
連番とUUIDの両方を振り出しておく? > ULIDを使うことにする

Posted by funa : 01:06 PM | Web | Comment (0) | Trackback (0)


June 1, 2024

GCP hands-off 3
■VPC(例: 10.0.0.0/16)
サブネット(Cloud SQL 用): 10.10.0.0/24(例: us-central1、VPC内)
サブネット(VPCコネクタ用): 10.8.0.0/28(RunからVPCへ通信用、VPC外)
 VPC コネクタのサブネットは 10.8.0.0/28 のような小さな範囲を使用、VPC外だがrun自体がVPC外だから?
 VPC コネクタはリージョン単位なので、Cloud Run と Cloud SQL を同じリージョンに配置するのが望ましい
Google Cloudの内部NW設計によりVPC内の異なるサブネット間でも通信可能
 VPC内なら異なるリージョンのサブネットでもOK(VPC自体には範囲を設定なしでサブネットでIPが被らなければOKかと
 追加の設定なしで、例えば us-central1 の VM から asia-northeast1 の Cloud SQLに直接アクセス可

■対象アセットに対する付与可能なロールの一覧表示
Full Resource Name(フルでのアセット名を探せる)

import google.auth
import googleapiclient.discovery

def view_grantable_roles(full_resource_name: str) -> None:
credentials.google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
service = googleapiclient.discovery.build('iam', 'v1', credentials credentials)
roles = (
service roles()
queryGrantableRoles (body=["fullResourceName": full_resource_name}).execute()
)
for role in roles["roles"]
if "title" in role:
print("Title: role["title"])
print("Name: role["name"])
if "description" in role:
print("Description:" + role["description"])
print("")

project_id = "prj"
#resource = f"//bigquery.googleapis.com/projects/prj/datasets/ds"
#resource + f"//bigquery googleapis.com/projects/prj/datasets/ds/tables/tbl"
resource = f"//cloudresourcemanager.googleapis.com/projects/{project_id}"
view_grantable_roles(resource)

■ロールの一覧表示
https://cloud.google.com/iam/docs/roles-overview?hl=ja#role-types
1)事前定義ロールの場合は roles.get() を使用します。
2)プロジェクトレベルのカスタムロールの場合は、projects.roles.get() を使用します。
3)組織レベルのカスタムロールの場合は、organizations.roles.get() を使用します。
 これら3種類で全てを網羅すると思われます
 projectIDがsys-のものはGAS、lifecycleStateがACTIVE以外のものも含まれるので注意

■bqへの書き込み
export GOOGLE_APPLICATION_CREDENTIALS="path/to/your-service-account-key.json"
pip install google-cloud-bigquery

from google.cloud import bigquery
client = bigquery Client()
#書き込み先のテーブル情報
table_ref = f"{project_id}.{dataset_id}.{table_id}"

#サンプルデータの生成
def generate_sample_data(num_rows)
data = [
{
"organization": f"org_(num_rows)",
"permission". "view",
}
for _ in range(num_rows)
]
return data

data_to_insert = generate_sample_data(5000)
errors = client.insert_rows_json(table_ref, data_to_insert)

if errors:
print("Errors occurred: {errors}")
else:
print("Data successfully written to BigQuery!")

■データカタログ
データアセットを検索する  |  Data Catalog Documentation  |  Google Cloud
Class SearchCatalogRequest (3.23.0)  |  Python client library  |  Google Cloud
サンプルで仕様書のAPIを使っているがqueryが空白刻みで入れる等の使い方が分かる

■BQスキーマ+ポリシータグ取得
from google.cloud import bigquery
def get_policy_tags_from_bq_table(project_id, dataset_id, table_id):
    print("################ bigquery.Client.get_table().schema start ################")
    print(f"Target table: {project_id}.{dataset_id}.{table_id}")
    bq_client = bigquery.Client()
    table = bq_client.get_table(f"{project_id}.{dataset_id}.{table_id}")
    schema = table.schema
    policy_tags = []
    for field in schema:
        print(f"Column: {field.name}")
        if field.policy_tags:
            tags = [tag for tag in field.policy_tags.names]
            policy_tags.extend(tags)
            print(f"Policy Tags: {tags}")
        else:
            print("> No Policy Tags assigned.")
    return policy_tags

PROJECT_ID = "prj"
DATASET_ID = "ds"
TABLE_ID = "test001"

policy_tags = get_policy_tags_from_bq_table(PROJECT_ID, DATASET_ID, TABLE_ID)
print("Collected Policy Tags:", policy_tags)

■ポリシータグ設定
from google.cloud import datacatalog_v1
from google.cloud import bigquery

PROJECT_ID = "prj"
DATASET_ID = "ds"
TABLE_ID = "tbl01"
COLUMN_NAME = "aaa"
POLICY_TAG_PROJECT = "prj"
POLICY_TAG_NAME = "projects/prj/locations/us/taxonomies/83893110/policyTags/11089383"

def list_taxonomy_and_policy_tag():
    print("############# Start #############")
    list_policy_tags = []
    client = datacatalog_v1.PolicyTagManagerClient()
    request = datacatalog_v1.ListTaxonomiesRequest(
        parent=f"projects/{POLICY_TAG_PROJECT}/locations/us"
    )
    try:
        page_result = client.list_taxonomies(request=request)
    except google.api_core.exceptions.PermissionDenied as e:
        print(f"Skipping project {POLICY_TAG_PROJECT} due to PermissionDenied error: {e}")
        return []
    except Exception as e:
        print(f"An error occurred for project {POLICY_TAG_PROJECT}: {e}")
        return []

    for taxonomy in page_result:
        print(f"############ Taxonomy display_name: {taxonomy.display_name} #############")
        print(f"############ Taxonomy name: {taxonomy.name} #############")
        request_tag = datacatalog_v1.ListPolicyTagsRequest(parent=taxonomy.name)
        try:
            page_result_tag = client.list_policy_tags(request=request_tag)
        except Exception as e:
            print(f"Error on {request_tag}: {e}")
            break
        for policy_tag in page_result_tag:
            print("Policy tag:")
            print(policy_tag)
            list_policy_tags.append({
                "project_id": POLICY_TAG_PROJECT,
                "taxonomy_display_name": taxonomy.display_name,
                "taxonomy_name": taxonomy.name,
                "policy_tag_name": policy_tag.name,
                "policy_tag_display_name": policy_tag.display_name,
            })
    return list_policy_tags

def update_table_schema_with_policy_tag(list_policy_tags):
    for policy_tag in list_policy_tags:
        if policy_tag['policy_tag_name'] == POLICY_TAG_NAME:
            print(
                f"Target policy tag:\n"
                f"  Project ID: {policy_tag['project_id']}\n"
                f"  Taxonomy Display Name: {policy_tag['taxonomy_display_name']}\n"
                f"  Taxonomy Name: {policy_tag['taxonomy_name']}\n"
                f"  Policy Tag Name: {policy_tag['policy_tag_name']}\n"
                f"  Policy Tag Display Name: {policy_tag['policy_tag_display_name']}"
            )
            client = bigquery.Client()
            table_ref = f"{PROJECT_ID}.{DATASET_ID}.{TABLE_ID}"
            table = client.get_table(table_ref)
            new_schema = []
            for field in table.schema:
                if field.name == COLUMN_NAME:
                    new_schema.append(
                        bigquery.SchemaField(
                            name=field.name,
                            field_type=field.field_type,  # Keep original field type
                            mode=field.mode,             # Keep original mode
                            description=field.description,
                            policy_tags=bigquery.PolicyTagList([POLICY_TAG_NAME]),
                        )
                    )
                else:
                    new_schema.append(field)
            table.schema = new_schema
            updated_table = client.update_table(table, ["schema"])
            print(
                f"Updated table {updated_table.project}.{updated_table.dataset_id}.{updated_table.table_id} schema\n"
                f"with policy_tag {POLICY_TAG_NAME} on the column {COLUMN_NAME} successfully."
            )
if __name__ == "__main__":
    list_policy_tags = list_taxonomy_and_policy_tag()
    update_table_schema_with_policy_tag(list_policy_tags)



■KSA問題
ブログ内で情報が分散、まとめたい
ワークロード(pod)毎にKSA1つ
ksaのtokenはk8s api用でgcp apiに使えない、exprireしない問題> Workload identity で解決する

Workload Identityの仕組み

Workload Identity がGKE クラスタで有効化されると、gke-metadata-server という DaemonSet がデプロイ
gke-metadata-server は Workload Identity を利用する上で必要な手続きを実行

SAの紐づけ
/// 現行
Workload identityを有効にして(autopilot でデフォルト有効) 
GCP側でKSAとGSAをIAM policy binding 
k8s側でKSAとGSAをkubectl annotate 
podでKSAを設定
/// 新型のKSA直接bind
workload identity federation ならGSAがなくなりKSAを直接bindできる
Workload identityを有効にして(autopilot でデフォルト有効)
GCP側でKSAにIAM policy binding

※混在するので現行のままが良いようです

■Workload identity federation(GCP外との連携)
まずWIF用のSAを作成する>SAに権限を付与する>
1)Workload identity provider+SAの情報をgithub actionに埋めて使う
 GitHub Actions から GCP リソースにアクセスする用途
2)Workload identity poolから構成情報をDLしAWSアプリに埋めて使う
 AWSからGCP リソースにアクセス
する用途
  gcloud auth login-cred-file=構成情報ファイルパス
3)Workload identity poolから構成情報をEKSのOIDC ID token のパスを指定しDL
 EKS から GCP リソースにアクセス
する用途
- EKSのマニフェストのサービスアカウントのアノテーションにIAMロールを記載
- EKSのサービスアカウントを使用したい Podのアノテーションに追加
- マウント先のパスを環境変数 GOOGLE APPLICATION_CREDENTIALS に設定
- Pod内でSDK またはコマンドにてGCP リソースヘアクセス可能か確認

Posted by funa : 03:24 PM | Web | Comment (0) | Trackback (0)


PhotoGallery


TWITTER
Search

Mobile
QR for cellphone  QR for smart phone
For mobile click here
For smart phone click here
Popular Page
#1Web
#2Hiace 200
#3Gadget
#4The beginning of CSSレイアウト
#5Column
#6Web font test
#7Ora Ora Ora Ora Ora
#8Wifi cam
#9みたらし団子
#10Arcade Controller
#11G Suite
#12PC SPEC 2012.8
#13Javascript
#14REMIX DTM DAW - Acid
#15RSS Radio
#16Optimost
#17通話SIM
#18Attachment
#19Summer time blues
#20Enigma
#21Git
#22Warning!! Page Expired.
#23Speaker
#24Darwinian Theory Of Evolution
#25AV首相
#26htaccess mod_rewite
#27/// BANGBOO BLOG /// From 2016-01-01 To 2016-01-31
#28竹書房
#29F☆ck CSS
#30Automobile Inspection
#31No ID
#32Win7 / Win10 Insco
#33Speaker
#34Arcade Controller
#35Agile
#36G Suite
#37Personal Information Privacy Act
#38Europe
#39Warning!! Page Expired.
#40GoogleMap Moblile
#41CSS Selectors
#42MySQL DB Database
#43Ant
#44☆od damnit
#45Teeth Teeth
#46Itinerary with a eurail pass
#47PHP Developer
#48Affiliate
#49/// BANGBOO BLOG /// From 2019-01-01 To 2019-01-31
#50/// BANGBOO BLOG /// From 2019-09-01 To 2019-09-30
#51/// BANGBOO BLOG /// On 2020-03-01
#52/// BANGBOO BLOG /// On 2020-04-01
#53Windows env tips
#54恐慌からの脱出方法
#55MARUTAI
#56A Rainbow Between Clouds‏
#57ER
#58PDF in cellphone with microSD
#59DJ
#60ICOCA
#61Departures
#62Update your home page
#63CSS Grid
#64恐慌からの脱出方法
#65ハチロクカフェ
#66/// BANGBOO BLOG /// On 2016-03-31
#67/// BANGBOO BLOG /// From 2017-02-01 To 2017-02-28
#68/// BANGBOO BLOG /// From 2019-07-01 To 2019-07-31
#69/// BANGBOO BLOG /// From 2019-10-01 To 2019-10-31
#70/// BANGBOO BLOG /// On 2020-01-21
#71Bike
#72Where Hiphop lives!!
#73The team that always wins
#74Tora Tora Tora
#75Blog Ping
#76無料ストレージ
#77jQuery - write less, do more.
#78Adobe Premire6.0 (Guru R.I.P.)
#79PC SPEC 2007.7
#80Google Sitemap
#81Information privacy & antispam law
#82Wifi security camera with solar panel & small battery
#83Hope get back to normal
#84Vice versa
#85ハイエースのメンテ
#86Camoufla
#87α7Ⅱ
#88Jack up Hiace
#89Fucking tire
#90Big D
#914 Pole Plug
#925-year-old shit
#93Emancipation Proclamation
#94Windows env tips
#95Meritocracy
#96Focus zone
#97Raspberry Pi
#98Mind Control
#99Interview
#100Branding Excellent
Category
Recent Entry
Trackback
Comment
Archive
<     June 2024     >
Sun Mon Tue Wed Thi Fri Sat
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Link