信頼はずっと、 挑戦はもっと。 株式会社コアテック CORE TECH

BLOG コアテックのメンバーが日々更新中! ※土日祝日を除きます

  • テクログ

    PICK UP!
    MySQLパーティショニングの話をします!基本的なことや導入方法はグーグル先生で検索するといっぱい出てくるのでそちらで。☆パーティショニングが適切なパターンそもそも自分が考えるパーティショニングが適切であるパターンは、・int型のカラムでステータスを判定している(パターン分岐がそれほど多くない)・一週間毎に生成されるようなデータなどつまりあまりパターンが多くなく、indexが効きづらいものですね。イメージとしては、別テーブルに分けるという選択肢が出てくるものが適切だと思います。(パーティショニングってそういうことやってる訳ですし)☆実際に導入した時に気をつけたこと導入した事例の仕様は・一週間毎にユーザーに紐づいた計算されたレコードができる(200万くらい)・そのデータを一週間ごとで参照する▼レコードを入れる前にパーティショニングまず、パーティションの導入はテーブルを新規作成するときに行いました。テストで2ヶ月分、1000万レコード程度が存在する想定の状態でパーティショニングをして見ましたが、全然終わりませんでしたwなるべくサービスを止める選択を取りたくなかったため、事前にパーティショニングされたテーブルにinsertする形になりました▼PHP側の定期バッチで一週間毎にパーティションを追加今回の仕様的に定期的なパーティション追加が必要でした。と言っても簡単なSQLを流すだけです。▼そもそもパーティションを考えたテーブル構成にするパーティションの判定をするカラムがuniqueなindexに含まれている必要があります。とはいえ複合主キーとかに含めるだけでもオッケーです。逆にここで想定していたカラムが上手くユニークにできない場合、おそらくパーティションするのに向いていないです。長々と書きましたが、結構導入は簡単です!パーティションを辞めるときにデータが消えたりもしませんし。気になる方はやってみましょう!
  • イベント

    すじこ

    2019.09.12

    すじこ

    イベント

    ブリーチと餃子の話

    お久しぶりです、すじこです。最近は台風が来たり急に暑くなったりと体調は大丈夫でしょうか?自分は気圧なのか分かりませんが、最近は後頭部あたりがずっとぎゅっとしています 心配〜突然ですが、自分の髪、最近すごく明るくないでしょうか?すごく怖いですよね?実は自分が一番ビビってます人生で一度は淡い色をかけたくて、そして人生で初めてブリーチで色を抜いて、更にそこからは落ち着いた色を入れたのですが、少し日が経っただけで元の色は落ちこの有様…この間も暗めの色を入れたのに、無駄にアッシュをかけたからか金を通り越して最近は苔みたいに緑になっていますワハー!外国人みたい!( ◜▿◝ )なんて思ったのもつかの間、元の暗めの色がちょっと恋しいです…たすけてそんな中、土曜に高校来の友人が遊びに来ました。友だちも髪染めを失敗しており、なんか前髪がヒカルの碁みたいになってました…最初はそれぞれの作った料理でお昼を食べようと話していたのですが、やっぱこれを機に染めようと意気投合し、気づいたらなぜか部屋でみんなで髪を染めていました。換気をしてたのに目や喉がぴりぴり…踏んだり蹴ったりですが、なんとか2人とも落ち着いた(?)髪色になりました!やったー!ブリーチの威力が強さを思い知ったここ最近でした。染める予定のある方は、今後を考えて準備しましょう…ちなみにその日友人が作ってくれた餃子の役前の姿です。プロ。美味しくて胃袋を鷲掴みにされました!ではでは〜〜
  • テクログ

     秘密裏に関数型を調べたりしているのですが、その一環でJavaScriptのreduce関数に触れてみました。 この関数はArray オブジェクトを1つにまとめます。以下のコードでは配列内にある数値を全て加算します。コード1const points = [50,5,200]; const reducer = (accumulator, current) => accumulator + current;   console.log(points.reduce(reducer)); 結果1 2つの変数 accumulator, current に入る値に最初は困惑しました。リファレンスを参照すると、累積値は、ひとつ前の戻り値、もしくは initialValue です引用元: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceとあります。「初期値が設定されていない状態で、ひとつ前の戻り値って・・・?」という感じでした。そこで少し書き直してログ出力すると以下のようになります。コード2const points = [50,5,200]; const reducer = function(accumulator, current){    console.log(accumulator, current);    return accumulator + current; }   points.reduce(reducer); 結果2 挙動を見ると、1回目のループでaccumulatorに最初の要素が入っていますね。「だとしたら、currentという変数名はおかしいのでは・・?」と思い、再びリファレンスを参照すると以下の注釈がありました。注: initialValue が指定されなかった場合は、reduce() は最初のインデックスを飛ばしてインデックス 1 から実行されます。initialValue が指定されていたらインデックス 0 から開始します。引用元: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce 初期値がない場合は0番目ではなく、1番目の要素から始まるようです。  reduce関数には4つの引数を取ることができますが、強そうなので仲良くなりたいものです。【参考記事】https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
  • レビュー

    うみ

    2019.09.10

    うみ

    レビュー

    YouTubeで動画配信

    お久しぶりです「うみ」ですです٩(๑òωó๑)۶本日は、YouTubeでの動画編集、Live配信ツールなどのご紹介を(ΦωΦ)フフフ…※あくまでも個人の感想です。まずは、周辺機器として ・AVerMediaのキャプチャーシリーズこちらです(人´∀`).☆.。.:*・゚個人的には、難しい設定が必要なくかなり重宝しております♪次に、Live配信ツール(PCにインストールするやーつですよ) ・XSplit無料(有料版も有り)なのに、色々と機能が使えて便利♪プラグインも充実しておりますゆえ、配信時に自身をワイプで入れたいなどの機能も入っております~(・∀・)そして、Live配信などで重宝するツール。デデデデデデデ・・・・・ジャーン!!! ・棒読みちゃん ・コメントビューアー「棒読みちゃん」はチャットを読み上げてくれるのですが、「コメントビューアー」との連携があって、初めて効果が発揮されます♪ 1:コメントビューアーでLive配信のURLをセット 2:コメントビューアーがチャットコメントを吸い出す 3:棒読みちゃんがコメントビューアーで吸い出したコメントを喋ってくれるな、流れになっています♪そして、最後に、動画編集ソフト!!こちらも無料ですが、かなり高機能!! ・Lightworksエフェクトやら、音声やら、文字やら色々と入れられます。高機能だけに、少しむずかしいですが、今の所重宝出来るツールとなっていますよ♪※あくまでも個人的に便利なツールの紹介です。※大事だから2回言うよ(´・ω・`)というわけで、今回は配信、動画編集の便利なツール紹介でした~(人´∀`).☆.。.:*・゚
  • テクログ

    そろそろ夏も終わりですね。はやく涼しくなってほしいですね。そういう気持ちからslackコマンドっぽいことをchatworkでしたい!ということになりました。-----------------------◆本当の経緯もとからslackでのchatops的なものは結構やっていたんですが、弊社slackだけではなくchatworkも使うんですね(ぼやかしで、chatworkもWebhookがあって、slackよりも機能や設定できることは少ないけど、なんとか似たことができそうだな、となったので作りました。-----------------------◆構成chatwork→APIGateway→Tokenやコマンドを検証し、振り分けるLambdaFunction→(SNS)→コマンドの実態LambdaFunction+chatworkへ結果返答わかりやすくするためTokenやコマンドを検証し、振り分けるLambdaFunction を [振り分けLambda]コマンドの実態Lambda を [実態Lambda]とします-----------------------◆設定を簡単に解説細かい設定は書きませんが、いろいろ試行錯誤するのも経験のうちですよね。(1)APIGatewayを作成chatworkのWebhookが叩く入り口です。URLがあればひとまずOKです。パス設定とかはおまかせします。(2)[振り分けLambda]の殻を作成APIGatewayの先のLambdaを作成します。(3)APIGatewayを設定(1)と(2)をつなぎまーす叩くとレスポンスが来るだけ確認しておくのもいいですね。(4)chatworkのWebhook設定chatworkにボットアカウントを作り、そのアカウントでWebhookの設定をします参考:https://help.chatwork.com/hc/ja/articles/115000169541-Webhook%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8BURLはAPIGatewayのURLで、イベントはルームイベントにしました。(なぜなら、目に見えないところではなく、その部屋だけで使ってほしいからです。)メッセージ作成のみ、にしました。(5)[振り分けLambda]を実装ソース!だよ!何もライブラリが要らないってのを重視。なんか貼ったら改行があれなのでまあそこはいいかんじにしてください。何かあってもこちらはサンプルですのでそこはいつものとおりご了承ください。見直すと入ってきた文字整形とか無理矢理感。chatworkはクライアントごとにメッセージの形式が微妙に違ったりしてね…必要な環境変数はCHATWORK_API_TOKEN (KMSで暗号化してある、postに使うchatworkのTokenWEBHOOK_TOKEN (渡ってきたchatworkのメッセージが正しいものかを判定するためのTokenです。# -*- coding: utf-8 -*- # chatwork commanderの入り口 import boto3 import json import logging import os import sys from datetime import datetime from botocore.exceptions import ClientError import copy import urllib.request, urllib.error from base64 import b64decode, b64encode import hmac import hashlib valid_command_list = ['こまんど1','こまんど2','こまんど3'] to_str = "[To:1111111111]" usage_str = "【コマンド一覧】\n" + \ "※それぞれのコマンドの使い方については[コマンド usage]を打って確認してください\n\n" + \ "こまんど1\n" + \ "こまんど2\n" + \ "こまんど3\n" SNS_ARN_PREFIX = "arn:aws:sns:ap-northeast-1:11111111111:chat_command_" #### #メイン #### def lambda_handler(event, context):   #先にイベントは取っておく(判定とかに使うから   eventjson = json.loads(json.dumps(event))   bodyjson = json.loads(eventjson['body'])   room_id    = str(bodyjson['webhook_event']['room_id'])   message_id = str(bodyjson['webhook_event']['message_id'])   body      = str(bodyjson['webhook_event']['body'])   account_id = str(bodyjson['webhook_event']['account_id'])   #まず   #[To:1111111111]   #がないなら無視(全メッセージ流れてくるから   if not to_str in body:     print('not me.END')     return {'statusCode': 200,'body': json.dumps('not me.END')}   #毎回kms使うのがやだからここでやってます   ENCRYPTED_WEBHOOK_TOKEN = os.environ['WEBHOOK_TOKEN']   WEBHOOK_TOKEN = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_WEBHOOK_TOKEN))['Plaintext']   ENCRYPTED_CHATWORK_API_TOKEN = os.environ['CHATWORK_API_TOKEN']   CHATWORK_API_TOKEN = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_CHATWORK_API_TOKEN))['Plaintext']   #Tokenの確認   if check_request(event, WEBHOOK_TOKEN) == True:     print("Token OK")     #body整形     command_text = body.replace('\n', '').replace('[To:1111111]', '').replace('aaaaa さん', '').replace('aaaaaさん', '').strip()     command_args = command_text.split(" ")     #コマンドの確認     command = command_args[0]     nextStatus = checkCommandStrAndMakeNextStatus(command, room_id, account_id, message_id, command_text, CHATWORK_API_TOKEN)     #nextStatusがTrue(続行)の場合、次のlambdaをSNSで呼ぶ     #続行ではない場合は特に何もせずreturnして終わり     if nextStatus == True:       message = {"room_id"   : room_id,             "command_args": command_args,             "account_id" : account_id,             "message_id" : message_id       }       #SNS_ARN_PREFIX+command がARNになるようになっている       sendSNS(message, SNS_ARN_PREFIX+command)     return {       'statusCode': 200,       'body': json.dumps('OK')     }   else:     print("Token NG")     return {       'statusCode': 403,       'body': json.dumps('NG')     } ##----------------------- def sendSNS(message, sns_TOPIC):   sns_client = boto3.client(     'sns'   )   #メッセージ整形   message=json.dumps(message)   message=json.dumps({'default': message, 'lambda': message})   response = sns_client.publish(     TopicArn=sns_TOPIC,     Subject='/lambda',     MessageStructure='json',     Message=message   )   print(response) #### #コマンドの内容を確認してchatwork通知 #また、今後の続行ステータスを返す #### def checkCommandStrAndMakeNextStatus(command, room_id, account_id, message_id, command_text, CHATWORK_API_TOKEN):   if command == 'usage':     postChatwork(usage_str,room_id, CHATWORK_API_TOKEN)     return False#終了   else:     if not command in valid_command_list:       postChatwork("対象コマンドがありません。\n"+usage_str,room_id, CHATWORK_API_TOKEN)       return False#終了     else:       #chatworkに受付状況を通知       postChatwork(         makeReplyMessage(account_id, room_id, message_id, command_text),         room_id,         CHATWORK_API_TOKEN       )       return True#続行 #### #メッセージをつけるだけ #### def makeReplyMessage(account_id, room_id, message_id, command_text):   return "コマンド:" + command_text + "\nを受け付けました。(コマンドの実態に渡しました)\nお待ち下さい。" #### #chatworkに通知 #### def postChatwork(message, room_id, CHATWORK_API_TOKEN):   print("in postChatwork")   END_POINT_BASE = "https://api.chatwork.com/v2"   END_POINT   = "/rooms/"   ACTION     = "/messages"   headers = { 'X-ChatWorkToken': CHATWORK_API_TOKEN }   data = { 'body': message }   data = urllib.parse.urlencode(data)   data = data.encode('utf-8')   # リクエストの生成と送信   post_message_url = END_POINT_BASE + END_POINT + room_id + ACTION   request = urllib.request.Request(post_message_url, data=data, method="POST", headers=headers)   with urllib.request.urlopen(request) as response:     response_body = response.read().decode("utf-8")     print(response_body) #参考 #https://qiita.com/ikedaosushi/items/b01183f207ea1db6a8d3 def check_request(event, WEBHOOK_TOKEN):   webhook_sig = event['headers']['X-ChatWorkWebhookSignature'].encode('utf-8')   sig = build_sig(event['body'], WEBHOOK_TOKEN)   is_valid = webhook_sig == sig   return is_valid def build_sig(body, WEBHOOK_TOKEN):   token_decode = b64decode(WEBHOOK_TOKEN)   sig = hmac.new(token_decode, body.encode('utf-8'), hashlib.sha256).digest()   sig_encoded = b64encode(sig)   return sig_encoded だいたいでいえば・メッセージはルームのものがすべて来るので、処理対象メッセージなのかを判定・tokenの確認・コマンドの確認・受け付けたことを返答・SNSで次のLambdaを呼ぶ(このSNSを一定の形式に統一することによって、後ろのコマンドを増やしやすくなってます。(6)実態Lambdaを呼ぶためのSNSを作るarn:aws:sns:ap-northeast-1:11111111111:chat_command_ ってなっているようにSNSをまず作りますたとえばmake_EC2みたいなコマンドだった場合、SNS名はchat_command_make_EC2になりますね。(7)[実態Lambda]を作るここは自分でつくってね!SNSを受け取って、分解して、処理をすればいいです。終わったらchatworkに通知したり、いろいろ内部でやればいいですね。夢が広がる。(8)SNSの先に[実態Lambda]を追加まあ追加するだけですあとはchatworkでボットにはなしかけたりしてテストをしてみよう!-----------------------コマンドを増やすときも、許可するコマンドを追加して、SNS作成コマンド実態Lambda作成だけでぽんぽんふえるよ!ルームを分けることによって、重要度ごとに使える人を分けられたりもします。以上夏休みの自由研究にどうぞ。もうおわってますか。-----------------------<以下はただの一覧用の画像でーす>
Read more

NEWS

ACCESS

〒153-0042 東京都目黒区青葉台3-6-28
住友不動産青葉台タワー12F
  • 渋谷駅「道玄坂上交番前の出口」より徒歩10分
  • 渋谷駅JR線・銀座線・東急東横線「西口」より徒歩14分
  • 渋谷駅半蔵門線・東急田園都市線・副都心線「1番出口」より徒歩14分
  • 東急田園都市線池尻大橋駅「東口」より徒歩7分
  • 京王井の頭線神泉駅「南口」より徒歩9分
詳しくはコチラ