- OCR(Optical Character Reconition) ๊ธฐ์ ์ ํ์ฉํ ๋ช ํจ ๊ด๋ฆฌ ๋ฐ Graph database(Neptune)์ ์ด์ฉํ ์ธ๋งฅ ์ถ์ฒ ์๋น์ค
- Architecture
- RESTful API Specification
- Lambda Functions Overview
- Build & Deploy
- References & Tips
- Limits
- Demo
- API Gateway
- Lambda Function
- Kinesis Data Stream
- Kinesis Data Firehorese
- Elasticsearch Service
- ElastiCache
- DynamoDB
- Neptune (Graph database)
- Textract
- S3
[Top]
-
Request
-
PUT
- /v1/{bucket}/{object}
URL Path parameters Description Required(Yes/No) Data Type bucket s3 bucket ์ด๋ฆ Yes String object s3 object ์ด๋ฆ Yes String -
ex) octember-use1 ๋ผ๋ s3 bucket์ bizcard-raw-img ๋๋ ํฐ๋ฆฌ ์๋์ bar_s20191101_125236.jpg ํ์ผ์ ์ ๋กํ๋ ์์
curl -X PUT "https://t2e7cpvqvu.execute-api.us-east-1.amazonaws.com/v1/octember-use1/bizcard-raw-img%2Fbar_s20191101_125236.jpg" \ --data @bar_s20191101_125236.jpg
-
-
Response
- No Data
[Top]
-
Request
-
GET
- /v1/search?query=isv&user=foobar&limit=10
Key Description Required(Yes/No) Data Type query ๊ฒ์ ์ง์์ด (name, job title, company, address) No String user ๊ฒ์ ๊ฒฐ๊ณผ ํํฐ๋ง ์กฐ๊ฑด (biz card๋ฅผ ๋ฑ๋กํ user id) No String limit ๊ฒ์ ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ ๊ฐ: 10) No Integer - (!) query ํน์ user ์ค ํ๋์ ๊ฐ์ ๋ฐ๋์ ํ์ํจ
-
ex)
curl -X GET "https://gfrgyj029q.execute-api.us-east-1.amazonaws.com/v1/search?query=architect&limit=2"
-
-
Response
-
meta ๋ฐ์ดํฐ
Key Description Data Type _index Elasticsearch Index ์ด๋ฆ String _type Elasticsearch Type ์ด๋ฆ String _id ๋ฌธ์ id String _score ๊ฒ์ ๊ฒฐ๊ณผ Relevance ์ ์ String _source JSON -
_source ๋ฐ์ดํฐ
Key Description Data Type doc_id ๋ฌธ์ id String name ์ด๋ฆ String phone_number ์ ํ ๋ฒํธ String email email ์ฃผ์ String job_title ํ์ฌ ์งํจ String company ํ์ฌ ์ด๋ฆ String addr ํ์ฌ ์ฃผ์ String is_alive ๋ฌธ์ ์ญ์ ์ฌ๋ถ ํ๋๊ทธ(0: ์ญ์ , 1: ๊ฒ์ ๊ฐ๋ฅํ ๋ฌธ์) Integer owner ๋ช ํจ ๋ฑ๋ก ์ฌ์ฉ์ id String image_id ๋ช ํจ ์ด๋ฏธ์ง ํ์ผ ์ด๋ฆ String content_id ์ค๋ณต ๋ฌธ์ ์ ๊ฑฐ๋ฅผ ์ํ ๋ฌธ์ ๋ด์ฉ id String created_at ๋ฌธ์ ์์ฑ ์๊ฐ String -
ex)
[ { "_index": "octember_bizcard", "_type": "bizcard", "_id": "dfb6c487", "_score": 0.5619609, "_source": { "addr": "508, Nonhyeon-ro, Gangnam-gu Seoul, 06141, Rep. of KOREA", "email": "[email protected]", "phone_number": "(+82 10) 2135 1294 ", "company": "aws", "name": "Foo Lee", "job_title": "Solutions Architect", "created_at": "2019-11-05T05:20:24Z", "doc_id": "dfb6c487", "image_id": "bar_s20191101_125236.jpg", "owner": "bar", "is_alive": 1, "content_id": "e2c266fc" } }, { "_index": "octember_bizcard", "_type": "bizcard", "_id": "8a78483a", "_score": 0.43445712, "_source": { "addr": "12Floor GS Tower, 508 Nonhyeon-ro Gangnam-gu, Seoul, Korea", "email": "[email protected]", "phone_number": "(+82 10) 7843 3795 ", "company": "aws", "name": "Bar Kim", "job_title": "ISV Partner Solutions Architect", "created_at": "2019-11-05T05:18:28Z", "doc_id": "8a78483a", "image_id": "foo_j20191101_125250.jpg", "owner": "foo", "is_alive": 1, "content_id": "3064ab8c" } } ]
-
[Top]
-
Request
-
GET
- /v1/pymk?user=foo%20bar&limit=10
Key Description Required(Yes/No) Data Type user ์ธ๋งฅ ์ถ์ฒ์ ๋ฐ๊ณ ์ ํ๋ ์ฌ์ฉ์ ์ด๋ฆ Yes String limit ์ธ๋งฅ ์ถ์ฒ ๊ฒฐ๊ณผ ๊ฐ์ (๊ธฐ๋ณธ ๊ฐ: 10) No Integer -
ex)
curl -X GET "https://y2xmtfbduf.execute-api.us-east-1.amazonaws.com/v1/pymk?user=foo%20bar&limit=2"
-
-
Response
-
body ๋ฐ์ดํฐ
Key Description Data Type name ์ด๋ฆ String phone_number ์ ํ ๋ฒํธ String email email ์ฃผ์ String job_title ํ์ฌ ์งํจ String company ํ์ฌ ์ด๋ฆ String score ์ธ๋งฅ ์ถ์ฒ ์ ์ Float -
ex)
[ { "name": [ "Bar Lee" ], "phone_number": [ "(+82 10) 3025 7502 " ], "company": [ "aws" ], "job_title": [ "Solutions Architect" ], "email": [ "[email protected]" ], "score": 4.0 }, { "name": [ "Foo Kim" ], "phone_number": [ "(+82 10) 7315 3970 " ], "company": [ "aws" ], "job_title": [ "Partner Solutions Architect" ], "email": [ "[email protected]" ], "score": 3.0 } ]
-
[Top]
Name | Description | Event Source | IAM Role | VPC | Etc |
---|---|---|---|---|---|
TriggerTextExtractFromS3Image | biz card ์ด๋ฏธ์ง๊ฐ s3์ ๋ฑ๋ก๋๋ฉด, text ๋ฐ์ดํฐ ์ถ์ถ ์์ ์ ์คํ ์ํค๋ ์์ | S3 ObjectCreated Event | DynamoDB Read/Write, Kinesis Data Stream Read/Write | No VPC | ETL |
GetTextFromS3Image | textract๋ฅผ ์ด์ฉํด์ biz card ์ด๋ฏธ์ง์์ text ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ์์ | Kinesis Data Stream | S3 Read/Write, DynamoDB Read/Write, Kinesis Data Stream Read/Write, Textract | ETL | |
UpsertBizcardToES | biz card์ text ๋ฐ์ดํฐ๋ฅผ ElasticSearch์ ์์ธํ๋ ์์ | Kinesis Data Stream | Kinesis Data Stream Read | ETL | |
UpsertBizcardToGraphDB | biz card์ text ๋ฐ์ดํฐ๋ฅผ graph database์ load ํ๋ ์์ | Kinesis Data Stream | Kinesis Data Stream Read | ETL | |
SearchBizcard | biz card๋ฅผ ๊ฒ์ํ๊ธฐ ์ํ ๊ฒ์ ์๋ฒ | API Gateway | Proxy Server | ||
RecommendBizcard | PYMK(People You May Know)๋ฅผ ์ถ์ฒํด์ฃผ๋ ์๋ฒ | API Gateway | Proxy Server |
[Top]
{user_id}_{image_id}.jpg
ex) foobar_i592134.jpg
{user_id}
๋ octember ์๋น์ค์ ๊ฐ์ ํ ํ์ ์์ด๋
- Input
{"s3_bucket": "{bucket name}", "s3_key": "{object key}"}
ex)
{"s3_bucket": "octember-use1", "s3_key": "bizcard-raw-img/foobar_i592134.jpg"}
- Output
- json data format
{ "s3_bucket": "{bucket name}", "s3_key": "{object key}", "owner": "{user_id}", "data": { "addr": "{address}", "email": "{email address}", "phone_number": "{phone number}", "company": "{company name}", "name": "{full name}", "job_title": "{job title}", "created_at": "{created datetime}" } }
- ex)
{ "s3_bucket": "octember-use1", "s3_key": "bizcard-raw-img/foobar_i592134.jpg", "owner": "foobar", "data": { "addr": "12Floor GS Tower, 508 Nonhyeon-ro, Gangnam-gu, Seoul 06141, Korea", "email": "[email protected]", "phone_number": "(+82 10) 1025 7049", "company": "aws", "name": "Foo Bar", "job_title": "Solutions Architect", "created_at": "2019-10-25T01:12:54Z" } }
- json data format
[Top]
- Input
GetTextFromS3Image
output data ์ฐธ๊ณ
- Output
- json data format
{ "doc_id": "md5({image file name})", "image_id": "{image file name}", "is_alive": {0 - dead, 1 - alive(default)}, "addr": "{address}", "email": "{email address}", "phone_number": "{phone number}", "company": "{company name}", "name": "{full name}", "job_title": "{job title}", "created_at": "{created datetime}" }
- ex)
{ "doc_id": "21cf827e", "image_id": "foobar_i592134.jpg", "is_alive": 1, "addr": "12Floor GS Tower, 508 Nonhyeon-ro, Gangnam-gu, Seoul 06141, Korea", "email": "[email protected]", "phone_number": "(+82 10) 1025 7049", "company": "aws", "name": "Foo Bar", "job_title": "Solutions Architect", "created_at": "2019-10-25T01:12:54Z" }
- json data format
[Top]
- Input
GetTextFromS3Image
output data ์ฐธ๊ณ
- Output
- Neptune Schema ์ฐธ๊ณ
[Top]
Bucket | Folder | Description |
---|---|---|
{bucket name} | bizcard-raw-img | ์ฌ์ฉ์๊ฐ ์ ๋ก๋ํ biz card image ์๋ณธ ์ ์ฅ์ |
{bucket name} | bizcard-by-user/{user_id} | ์ ๋ก๋๋ biz card image๋ฅผ ์ฌ์ฉ์๋ณ๋ก ๋ณ๋๋ก ๋ณด๊ดํ๋ ์ ์ฅ์ |
{bucket name} | bizcard-text/{YYYY}/{mm}/{dd}/{HH} | biz card image์์ ์ถ์ถํ text ๋ฐ์ดํฐ ์ ์ฅ์; ๊ฒ์์ ์ํ ์ฌ์์ธ ๋ฐ ๋ฐฐ์น ํํ์ ํ ์คํธ ๋ถ์์ ์ํ ๋ฐฑ์ ์ ์ฅ์ |
[Top]
primary key(partition key) | s3_bucket | s3_key | mts | status |
---|---|---|---|---|
{user_id}_{image_id}.jpg | s3 bucket | s3 object key | last modified time(yyyymmddHHMMSS) | processing status {START, PROCESSING, END} |
foobar_i592134.jpg | octember-use1 | bizcard-raw-img/foobar_i592134.jpg | 20191025011254 | END |
[Top]
- Vertex
Vertex Label | Property | Description |
---|---|---|
person | id, name, email, phone_number, job_title, company | biz card์ ์๋ ์ธ๋ฌผ ์ ๋ณด |
person | { |
- Edge
Edge Label | Property | Description |
---|---|---|
knows | weight | biz card๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ฌ๋๋ค ๊ฐ์ ๊ด๊ณ (weight: ๊ด๊ณ์ ์ค์๋) |
knows | {"weight": 1.0} |
[Top]
-
Getting Started With the AWS CDK๋ฅผ ์ฐธ๊ณ ํด์ cdk๋ฅผ ์ค์นํ๊ณ , cdk๋ฅผ ์คํํ ๋ ์ฌ์ฉํ IAM User๋ฅผ ์์ฑํ ํ,
~/.aws/config
์ ๋ฑ๋กํจ ์๋ฅผ ๋ค์ด์, cdk_user๋ผ๋ AdministratorAccess ๊ถํ์ ๊ฐ๋ IAM User๋ฅผ ์์ฑ ํ ํ, ์๋์ ๊ฐ์ด~/.aws/config
์ ์ถ๊ฐ๋ก ๋ฑ๋กํจ$ cat ~/.aws/config [profile cdk_user] aws_access_key_id=AKIAI44QH8DHBEXAMPLE aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY region=us-east-1
-
Lambda Layer์ ๋ฑ๋กํ Python ํจํค์ง๋ฅผ ์์ฑํด์ s3 bucket์ ์ ์ฅํจ. ์๋ฅผ ๋ค์ด, elasticsearch, gremlinpython, redis ํจํค์ง๋ฅผ Lambda Layer์ ๋ฑ๋ก ํ ์ ์๋๋ก octember-resources๋ผ๋ ์ด๋ฆ์ s3 bucket์ ์์ฑ ํ, ์๋์ ๊ฐ์ด ์ ์ฅํจ.
$ aws s3 ls s3://octember-resources/var/ 2019-10-25 08:38:50 0 2019-10-25 08:40:28 1294387 octember-es-lib.zip 2019-10-29 08:35:28 1311836 octember-gremlinpython-lib.zip 2019-10-30 07:41:07 141534 octember-redis-lib.zip
์ฐธ๊ณ : AWS Lambda Layer์ ๋ฑ๋กํ Python ํจํค์ง ์์ฑ ์์
-
cdk๋ฅผ ์ด์ฉํด์ Amazon ElasticSearch Service๋ฅผ VPC ๋ด์ ์์ฑํ๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ด Amazon ElasticSearch Service๋ฅผ ์ํ service linked role ์ ๋ฏธ๋ฆฌ ์์ฑํ๋ค.
$ aws iam create-service-linked-role --aws-service-name es.amazonaws.com
-
์์ค ์ฝ๋๋ฅผ git์์ ๋ค์ด๋ก๋ ๋ฐ์ ํ, cdk.context.json ํ์ผ์
lib_bucket_name
๋ผ๋ key ๊ฐ์ผ๋ก lambda layer์ ๋ฑ๋กํ ํจํค์ง๊ฐ ์ ์ฅ๋ s3 bucket ์ด๋ฆ์ ์ค์ ํ ํ,cdk deploy
๋ช ๋ น์ด๋ฅผ ์ด์ฉํด์ ๋ฐฐํฌํจ$ git clone [email protected]:aws-samples/social-graph-based-people-recommender-using-amazon-neptune-and-textract.git $ cd octember-bizcard $ cat <<EOF > cdk.context.json > { > "lib_bucket_name": "octember-resources" > } > EOF $ python3 -m venv .env $ source .env/bin/activate (.env) $ pip install -r requirements.txt (.env) $ cdk --version 2.10.0 (build e5b301f) (.env) $ cdk context -j { "lib_bucket_name": "octember-resources" } (.env) $ export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query Account --output text) (.env) $ export CDK_DEFAULT_REGION=us-east-1 (.env) $ cdk bootstrap aws://${CDK_DEFAULT_ACCOUNT}/${CDK_DEFAULT_REGION} (.env) $ cdk --profile=cdk_user synth Resources: OctemberVPC04CAC20C: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default ...... AssetParametersa05ca8352deadc2f1972c4fb21555d99120d0510cccb81d30b285153803df7ddS3VersionKey52AC24C7: Type: String Description: S3 key for asset version "a05ca8352deadc2f1972c4fb21555d99120d0510cccb81d30b285153803df7dd" AssetParametersa05ca8352deadc2f1972c4fb21555d99120d0510cccb81d30b285153803df7ddArtifactHashEF43BE8F: Type: String Description: Artifact hash for asset "a05ca8352deadc2f1972c4fb21555d99120d0510cccb81d30b285153803df7dd" SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter: Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 (.env) $ cdk --profile=cdk_user deploy
โ
cdk bootstrap ...
๋ช ๋ น์ด๋ CDK toolkit stack ๋ฐฐํฌ๋ฅผ ์ํด ์ต์ด ํ๋ฒ๋ง ์คํ ํ๊ณ , ์ดํ์ ๋ฐฐํฌํ ๋๋ CDK toolkit stack ๋ฐฐํฌ ์์ดcdk deploy
๋ช ๋ น์ด๋ง ์ํํ๋ฉด ๋ฉ๋๋ค. -
๋ฐฐํฌํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ญ์ ํ๋ ค๋ฉด,
cdk destroy
๋ช ๋ น์ด๋ฅผ ์๋์ ๊ฐ์ด ์คํ(.env) $ cdk --profile=cdk_user destroy
โ
cdk destroy
๋ฅผ ์ํ ์, CloudWatch Log Groups, S3 Bucket, DynamoDB ํ ์ด๋ธ์ ์๋์ผ๋ก ์ญ์ ๋์ง ์์ผ๋ฏ๋ก, ๋ฐ๋์ ์ง์ ์ญ์ ํด์ผ ํฉ๋๋ค.
cdk ls
list all stacks in the appcdk synth
emits the synthesized CloudFormation templatecdk deploy
deploy this stack to your default AWS account/regioncdk diff
compare deployed stack with current statecdk docs
open CDK documentation
[Top]
- s3 bucket์ ์์ฑํจ; ์๋ฅผ ๋ค์ด์ us-east-1 ๋ฆฌ์ ์ octember-use1 ๋ผ๋ ์ด๋ฆ์ bucket์ ์์ฑํจ
- ์์ฑ๋ s3 bucket ์์ bizcard-raw-img, bizcard-by-user ๋๋ ํฐ๋ฆฌ๋ฅผ ์์ฑํจ
$ aws s3 ls s3://octember-use1/ PRE bizcard-by-user/ PRE bizcard-raw-img/
- API Gateway + S3๋ฅผ ์ฐธ๊ณ ํด์ s3์ ์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ ํ๋ RESTful API๋ฅผ ์์ฑํจ
- Kinesis Data Stream๋ฅผ ์ฐธ๊ณ ํด์ octember-bizcard-img ์ด๋ฆ์ Kinesis Data Stream์ ์์ฑํจ
- DynamoDB๋ฅผ ์ฐธ๊ณ ํด์ OctemberBizcardImg ์ด๋ฆ์ DynamoDB ํ ์ด๋ธ์ ์์ฑํจ; primary partition key๋ฅผ string ํ์ ์ผ๋ก ํ๊ณ , ์ด๋ฆ์ image_id ๋ผ๊ณ ์ค์ ํจ
- Lambda๋ฅผ ์ฐธ๊ณ ํด์ TriggerTextExtractFromS3Image ๋ผ๋ lambda function์ ์์ฑํ๊ณ , TriggerTextExtractFromS3Image ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- TriggerTextExtractFromS3Image ์์ฑ ์, REGION_NAME, KINESIS_STREAM_NAME, DDB_TABLE_NAME ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Kinesis Data Stream ์ด๋ฆ, DynamoDB ํ
์ด๋ธ ์ด๋ฆ์ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 KINESIS_STREAM_NAME=octember-bizcard-img DDB_TABLE_NAME=OctemberBizcardImg
- Kinesis Data Stream๋ฅผ ์ฐธ๊ณ ํด์ octember-bizcard-text ์ด๋ฆ์ผ๋ก Kinesis Data Stream์ ์์ฑํจ
- Lambda๋ฅผ ์ฐธ๊ณ ํด์ GetTextFromS3Image ๋ผ๋ lambda function์ ์์ฑํ๊ณ , GetTextFromS3Image ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- GetTextFromS3Image ์์ฑ ์, REGION_NAME, KINESIS_STREAM_NAME, DDB_TABLE_NAME ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Kinesis Data Stream ์ด๋ฆ, DynamoDB ํ
์ด๋ธ ์ด๋ฆ์ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 KINESIS_STREAM_NAME=octember-bizcard-text DDB_TABLE_NAME=OctemberBizcardImg
[Top]
- Elasticsearch Service๋ฅผ ์ฐธ๊ณ ํด์ VPC ๋ด์ octember ๋ผ๋ domain ์ด๋ฆ์ผ๋ก Elasticsearch cluster๋ฅผ ์์ฑํจ
- Kinesis Data Firehorse๋ฅผ ์ฐธ๊ณ ํด์ Source๋ฅผ octember-bizcard-text, Destination์ s3 bucket(์: octember-use1)์ผ๋ก ์ค์ ํจ
s3 destination์ prefix๋ฅผbizcard-text/
๋ก ์ค์ ํจ - Lambda๋ฅผ ์ฐธ๊ณ ํด์ UpsertBizcardToES ๋ผ๋ lambda function์ ์์ฑํ๊ณ , UpsertBizcardToES ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- UpsertBizcardToES ์์ฑ ์, REGION_NAME, ES_HOST ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Elasticsearch cluster endpoint ์ฃผ์๋ฅผ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 ES_HOST=https://vpc-octember-ykpng6bf4qn1599enqv2f7rikf.us-east-1.es.amazonaws.com
- ElasitCache๋ฅผ ์ฐธ๊ณ ํด์ ๊ฒ์ ์ง์ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํ๊ธฐ ์ํ ์บ์ฌ ์๋ฒ๋ฅผ ์์ฑํจ
์๋ฅผ ๋ค์ด octember-es-cache ๋ผ๋ ์ด๋ฆ์ Redis๋ฅผ ์์ฑํจ - Lambda๋ฅผ ์ฐธ๊ณ ํด์ SearchBizcard ๋ผ๋ ๊ฒ์ ์๋ฒ๋ก ์ฌ์ฉํ lambda function์ ์์ฑํ๊ณ , SearchBizcard ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- SearchBizcard ์์ฑ ์, REGION_NAME, ES_HOST, ELASTICACHE_HOST ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Elasticsearch cluster endpoint ์ฃผ์, ElastiCache endpoint ์ฃผ์๋ฅผ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 ES_HOST=https://vpc-octember-ykpng6bf4qn1599enqv2f7rikf.us-east-1.es.amazonaws.com ELASTICACHE_HOST=octember-es-cache.xqep4c.0001.use1.cache.amazonaws.com
- ๊ฒ์ ์๋ฒ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ API Gateway + Lambda๋ฅผ ์ฐธ๊ณ ํด์ api gateway์ SearchBizcard ๋ผ๋ lambda function์ ๋ํฉํ RESTful API๋ฅผ ์์ฑํจ
[Top]
- Neptune๋ฅผ ์ฐธ๊ณ ํด์ VPC ๋ด์ octember-bizcard ๋ผ๋ ์ด๋ฆ์ graph database๋ฅผ ์์ฑํจ
- Lambda๋ฅผ ์ฐธ๊ณ ํด์ UpsertBizcardToGraphDB ๋ผ๋ lambda function์ ์์ฑํ๊ณ , UpsertBizcardToGraphDB ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- UpsertBizcardToGraphDB ์์ฑ ์, REGION_NAME, NEPTUNE_ENDPOINT ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Neptune endpoint ์ฃผ์๋ฅผ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 NEPTUNE_ENDPOINT=octember-bizcard.64ocu93lfjfj.us-east-1.neptune.amazonaws.com
- ElasitCache๋ฅผ ์ฐธ๊ณ ํด์ ์ธ๋งฅ ์ถ์ฒ ๊ฒฐ๊ณผ๋ฅผ ์บ์ฑํ๊ธฐ ์ํ ์บ์ฌ ์๋ฒ๋ฅผ ์์ฑํจ
์๋ฅผ ๋ค์ด octember-neptune-cache ๋ผ๋ ์ด๋ฆ์ Redis๋ฅผ ์์ฑํจ - Lambda๋ฅผ ์ฐธ๊ณ ํด์ RecommendBizcard ๋ผ๋ ๊ฒ์ ์๋ฒ๋ก ์ฌ์ฉํ lambda function์ ์์ฑํ๊ณ , RecommendBizcard ๋๋ ํฐ๋ฆฌ ๋ด์ ์์ค ์ฝ๋๋ฅผ ๋ณต์ฌํด์ lambda function code์ ๋ฑ๋กํจ
- RecommendBizcard ์์ฑ ์, REGION_NAME, NEPTUNE_ENDPOINT, ELASTICACHE_HOST ๋ฑ์ ํ๊ฒฝ ๋ณ์์ ๋ฆฌ์ ์ด๋ฆ, Neptune endpoint ์ฃผ์, ElastiCache endpoint ์ฃผ์๋ฅผ ์๋ง๊ฒ ์ค์ ํจ
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ด ํ๊ฒฝ ๋ณ์ ๊ฐ์ ์ค์ ํจREGION_NAME=us-east-1 NEPTUNE_ENDPOINT=octember-bizcard.64ocu93lfjfj.us-east-1.neptune.amazonaws.com ELASTICACHE_HOST=octember-neptune-cache.2rb5x2.0001.use1.cache.amazonaws.com
- ์ธ๋งฅ ์ถ์ฒ ์๋ฒ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ API Gateway + Lambda๋ฅผ ์ฐธ๊ณ ํด์ api gateway์ RecommendBizcard ๋ผ๋ lambda function์ ๋ํฉํ RESTful API๋ฅผ ์์ฑํจ
[Top]
- ์์ต์: Amazon S3๊ณผ ํจ๊ป AWS Lambda ์ฌ์ฉ
- AWS Lambda ๊ณ์ธต
- Lambda Layer์ ๋ฑ๋กํ Elasticsearch Python ํจํค์ง ์์ฑ ์์
- virtualenv๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
$ python3 -m venv es-lib # virtual environments์ ์์ฑํจ $ cd es-lib $ source bin/activate (es-lib) $ mkdir -p python_modules # ํ์ํ ํจํค์ง๋ฅผ ์ ์ฅํ ๋๋ ํฐ๋ฆฌ ์์ฑ (es-lib) $ pip install 'elasticsearch>=7.0.0,<7.11' requests requests-aws4auth -t python_modules # ํ์ํ ํจํค์ง๋ฅผ ์ฌ์ฉ์๊ฐ ์ง์ ํ ํจํค์ง ๋๋ ํฐ๋ฆฌ์ ์ ์ฅํจ (es-lib) $ deactivate $ mv python_modules python # ์ฌ์ฉ์๊ฐ ์ง์ ํ ํจํค์ง ๋๋ ํฐ๋ฆฌ ์ด๋ฆ์ python์ผ๋ก ๋ณ๊ฒฝํจ (python ๋๋ ํฐ๋ฆฌ์ ํจํค์ง๋ฅผ ์ค์นํ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์ด๋ฆ์ ๋๋ ํฐ๋ฆฌ์ ํจํค์ง๋ฅผ ์ค์น ํ, ๋๋ ํฐ๋ฆฌ ์ด๋ฆ์ ๋ณ๊ฒฝํจ) $ zip -r es-lib.zip python/ # ํ์ํ ํจํค์ง๊ฐ ์ค์น๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ์์ถํจ $ aws s3 mb s3://my-bucket-for-lambda-layer-packages # ์์ถํ ํจํค์ง๋ฅผ ์ ๋ก๋ํ s3 bucket์ ์์ฑํจ $ aws s3 cp es-lib.zip s3://my-bucket-for-lambda-layer-packages/var/ # ์์ถํ ํจํค์ง๋ฅผ s3์ ์ ๋ก๋ ํ ํ, lambda layer์ ํจํค์ง๋ฅผ ๋ฑ๋กํ ๋, s3 ์์น๋ฅผ ๋ฑ๋กํ๋ฉด ๋จ
- Docker๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ - How do I create a Lambda layer using a simulated Lambda environment with Docker?
$ cat <<EOF > requirements.txt > elasticsearch>=7.0.0,<7.11 > requests==2.23.0 > requests-aws4auth==0.9 > EOF $ docker run -v "$PWD":/var/task "public.ecr.aws/sam/build-python3.7" /bin/sh -c "pip install -r requirements.txt -t python/lib/python3.7/site-packages/; exit" $ zip -r es-lib.zip python > /dev/null $ aws s3 mb s3://my-bucket-for-lambda-layer-packages $ aws s3 cp es-lib.zip s3://my-bucket-for-lambda-layer-packages/var/
- virtualenv๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ์์ต์: API Gateway์์ Amazon S3 ํ๋ก์๋ก REST API ์์ฑ
- (API Gateway ๊ธฐ๋ณธ ํ์ ์ฐฝ์์) API์ Settings์์ Binary Media Types์ ํ์ํ ๋ฏธ๋์ด ์ ํ(์: image/png, image/jpg)์ ์ ๋ ฅ ํ ์ ์ฅํจ
- S3์ ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๋ ๊ฒฝ์ฐ ํตํฉ ์์ฒญ(Integration Request)์ HTTP Headers์์
x-amz-acl
ํค๋ ์๋ตํ๊ฑฐ๋ ์ฌ๋ฐ๋ฅธ ACL ๊ฐ์ ์ค์ ํด์ผ ํจ - ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋ํ๊ฑฐ๋ ๋ค์ด๋ก๋ํ๋ ค๋ฉด, ํตํฉ ์์ฒญ(์
๋ก๋ํ๋ ๊ฒฝ์ฐ) ๋ฐ ํตํฉ ์๋ต(๋ค์ด๋ก๋ํ๋ ๊ฒฝ์ฐ)์์ ์ฝํ
์ธ ์ฒ๋ฆฌ(Content Handling)๋ฅผ
Convert to binary (if needed)
๋ก ์ค์ ํด์ผ ํจ
- Neptune ์์ํ๊ธฐ
- Using the Neptune Workbench with Jupyter Notebooks
- Let Me Graph That For You โ Part 1 โ Air Routes
- aws-samples/amazon-neptune-samples
- Apache TinkerPopTM
- Amazon Kinesis Data Firehose ์ ์ก ์คํธ๋ฆผ ์์ฑ
- Loading Streaming Data into Amazon ES from Amazon Kinesis Data Firehose
[Top]
- Amazon Textract ์๋น์ค๊ฐ ์ง์ํ๋ ์ธ์ด๊ฐ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์ ํ์ธ ํ ์ฌ์ฉ์ด ํ์ํจ (ํ๊ตญ์ด๋ ํ์ฌ 2019-11-11 ๊น์ง ์ง์๋์ง ์๊ณ ์์)
- ๋ช ํจ ์ด๋ฏธ์ง(jpeg/png) ํฌ๊ธฐ๋ 5MB ์๊ฑฐ๋ ๊ฐ์์ผ ํจ
Amazon Kinesis Data Firehose๋ ํ์ฌ (2019-11-11) VPC ๋ด์ ์๋ Elasticsearch domains์ ๋ฐ์ดํฐ๋ฅผ loading ํ๋ ๊ฒ์ ์ง์ ํ์ง ์์Note: Amazon Kinesis Data Firehose currently doesn't support VPC domains.- Amazon Kinesis Data Firehose adds support for streaming data delivery to an Amazon Elasticsearch Service domain in an Amazon Virtual Private Cloud (VPC) (2020-04-24)
[Top]
-
์ฌ์ ์ค๋น ์์
- ๋ค์๊ณผ ๊ฐ์ IAM Policy๋ฅผ ๊ฐ๋ IAM User๋ฅผ ์์ฑํจ.
๊ณผ ๋ ๊ฐ์์ AWS ์ ์ ํ๊ฒ ์์ ํจ.์๋ฅผ ๋ค์ด, ์ด{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:getObject*", "s3:listObject*", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::octember-bizcard-<availability-zone>-<account-id>/bizcard-raw-img/*" }, { "Effect": "Allow", "Action": [ "execute-api:Invoke", "execute-api:ManageConnections" ], "Resource": "arn:aws:execute-api:*:*:*" } ] }
us-east-1
์ด๊ณ , ์123456789012
๋ผ๋ฉด, ์๋์ ๊ฐ์ IAM Policy๋ฅผ ๊ฐ๋ IAM User๋ฅผ ์์ฑํจ.{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:getObject*", "s3:listObject*", "s3:PutObject" ], "Resource": "arn:aws:s3:::octember-bizcard-us-east-1-123456789012/bizcard-raw-img/*" }, { "Effect": "Allow", "Action": [ "execute-api:Invoke", "execute-api:ManageConnections" ], "Resource": "arn:aws:execute-api:*:*:*" } ] }
- ์์ ์์ฑํ IAM User (์: octember-bizcard-uploader)์ AccessKey, SecretKey๋ฅผ ๋ก์ปฌ PC์ ๋ค์ด๋ก๋ ํจ.
- ๋ค์๊ณผ ๊ฐ์ IAM Policy๋ฅผ ๊ฐ๋ IAM User๋ฅผ ์์ฑํจ.
-
Postman์ ์ด์ฉํด์ ์ด๋ฏธ์ง ์ ๋ก๋ API๋ก ๋ช ํจ์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ
- Postman์์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Authorization ํญ์์ TYPE์ AWS Signature๋ก ์ ํํ๊ณ , S3 Read/Write ๊ถํ์ ๊ฐ์ง ์ฌ์ฉ์
(์: octember-bizcard-uploader)์ AccessKey, SecretKey๋ฅผ ๋ฑ๋กํ๊ณ , AWS Region์ ์ค์ ํจ
- Headers ํญ์ ์ ํํ๊ณ , Key, Value๋ฅผ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ถ๊ฐํจ
- Body ํญ์์ binary๋ฅผ ์ ํํ๊ณ , Select File ๋ฒํผ์ ๋๋ฌ์, ์ ์กํ ํ์ผ์ ์ถ๊ฐํจ
- ์ ์กํ ์ด๋ฏธ์ง ํ์ผ์ด ์ถ๊ฐํ ํ, Send ๋ฒํผ์ ๋๋ฌ์ PUT ๋ฉ์๋๋ฅผ ์คํํจ
- Postman์์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Authorization ํญ์์ TYPE์ AWS Signature๋ก ์ ํํ๊ณ , S3 Read/Write ๊ถํ์ ๊ฐ์ง ์ฌ์ฉ์
(์: octember-bizcard-uploader)์ AccessKey, SecretKey๋ฅผ ๋ฑ๋กํ๊ณ , AWS Region์ ์ค์ ํจ
[Top]
- OctemberTM ์ฌ์ฉ์๋ณ๋ก ์์ ์ ๋ช
ํจ ์ด๋ฏธ์ง๋ฅผ ํ๋์ฉ ๋ฑ๋กํจ;
์๋ฅผ ๋ค์ด samples ๋๋ ํฐ๋ฆฌ์์ edy_a0653895773.jpg, poby_a5411145874.jpg, pororo_a2553858703.jpg ๋ช ํจ ์ด๋ฏธ์ง๋ฅผ ๋ฑ๋กํจ
๋ฐ๋์ edy_a0653895773.jpg, poby_a5411145874.jpg, pororo_a2553858703.jpg ๋ช ํญ ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ฅ ๋จผ์ ๋ฑ๋กํด์ผ ํจ
- OctemberTM ์ฌ์ฉ์๋ณ๋ก ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๋ช
ํจ ์ด๋ฏธ์ง๋ฅผ ๋ฑ๋กํจ;
์๋ฅผ ๋ค์ด OctemberTM ์ฌ์ฉ์ Edy Kim์ ๋ช ํจ ์ด๋ฏธ์ง edy_cr8677419714.jpg, edy_ha3800766762.jpg, edy_pb5411145874.jpg ์ ๋ฑ๋กํ ํ, ๋๋จธ์ง ์ฌ์ฉ์๋ค(Poby Kim, Pororo Kim)์ ๋ช ํจ ์ด๋ฏธ์ง๋ ๋ฑ๋กํจ - samples ๋๋ ํฐ๋ฆฌ ์์ ์๋ ๋ชจ๋ ๋ช
ํจ์ ๋ฑ๋กํ๋ฉด, ์๋์ ๊ฐ์ ์ธ๋งฅ ๊ด๊ณ๊ฐ ์์ฑ๋จ
- ๋ฑ๋ก๋ ๋ช
ํจ์ ์ฐพ๊ธฐ ์ํด์ ์ฌ์ฉ์ ์ด๋ฆ์ด๋ ์ง์ฅ๋ช
, ์ง๋ฌด(Job title) ๋ฑ์ผ๋ก ๊ฒ์ํด์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํจ
- ์ธ๋งฅ ์ถ์ฒ api๋ฅผ ์ด์ฉํด์ OctemberTM ํ์์๊ฒ ์ถ์ฒํ ๋งํ ์ฌ๋์ ์ฐพ์๋ด
[Top]
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.