Euiyoung Hwang (marieuig@gmail.com) / Linkedin(https://www.linkedin.com/in/euiyoung-hwang/) : Search, Data & AI Software Engineer
ELASTICSEARCH DEVELOPER II, San Francisco, USA, CORE ELASTICSEARCH: DEVELOPER, San Francisco, USA, CORE ELASTICSEARCH: OPERATIONS, San Francisco, USA
, SAS@Data Scientist, South Korea, Search: Advanced Deployments (Part 3), Taiwan,
Google Apps Partner Training Apps200 - Technical Bootcamp, South Korea, Google Apps Partner Training Apps200 - Technical Bootcamp, South Korea
Google, Microsoft Certified Application Developer (MCAD) .NET, Microsoft Certified Professional (MCP)docker-compose.yml
such as Ansible/Fabric automation tools, Apach Kafka, Rabbitmq, Apache Hadoop, Search Engine such as Elasticsearch/Opensearch/Solr, Elasticsearch Curator, Logstash, ELK, Monitoring such as Prometheus, Grafana, Builtin-Exporter/Custom-Export for Observability, Alertmanager, Postgres an so on with docker and python virtualenv and test them using some scripts (https://github.com/euiyounghwang/python-platform-engine/tree/master)CI/CD
, https://github.com/euiyounghwang/python-CICD-fastapi-basic and other repos for master/dev/new pull requests branch with slack’s notification) platform that allows you to automate your build, test, and deployment pipeline by using CircleCI & GitHub ActionsBuilding Django & Django REST Framework (DRF, Swagger with 'drf_yasg'
) with Poetry dependency management and Python Virtual Enviroment by using Postgres & Elasticsearch : REST API for DB model with CRUD, REST API & Frontend (https://github.com/euiyounghwang/python-django/blob/master/screenshots/Django-rest_ui-search.png) with template for search results, unit tests for elasticsearch query, rest_api for Postgres, Redis, Elasticsearch using pytest-django, Ingestion Script for Database with Postgres, Mongodb, Push Docker image into DockerHub with my account after running on CircleCi (Repo : https://github.com/euiyounghwang/python-django/tree/master)
I have ten years of experience in working with a modern search platform (Elasticsearch, Google Search Appliance with Google Apps) and in building data pipelines(e.g https://github.com/euiyounghwang/python-search) & rest api services around it as a search engineer/senior software engineer. Especially, I am an expert in the Search Engine with a bunch of api from elasticsearch and rest_api environment using Python Web Stacks with Docker because I have been handling the entire version of ES from 1.7 up to 7.9 (i.e building ES cluster from the scrach, handling index mappings with a lof of analyzers and resolving complex query based on domain needs)
In FiscalNote (2022.07 ~ 2023.07), I contributed to improve search relevance with complex queries such as func_score to adjust the weight to search results and query performance with clusters. In more detail, I did the following:
In particular, I remember that I have been building and implementing ‘Enterprise Search Services’ for seven years based on Elasticsearch in South Korea. As a result of my contributions that I was having a success story interview at the elastic on seoul conference(https://www.youtube.com/watch?v=qu0IXwi3Fq0). At that time, I participated in the Google search engine replacement project(https://www.linkedin.com/pulse/elastic-tour-seoul-posco-ict-euiyoung-hwang/) as project leader and senior software engineer.
The screenshots attached below are for the Success Story with Elasticsearch Interview, Elastic on Seoul Conference, 2018 (https://www.elastic.co/customers/posco) when i worked as Senior Software Engineer & Search/Data Engineer at POSC ICT, South Korea (Received an award in POST ICT, 2016, https://media.licdn.com/dms/image/C512DAQGqaGMRMAXk9w/profile-treasury-image-shrink_1920_1920/0/1597560813194?e=1694487600&v=beta&t=sYbj3Kip8j_opHS_GB2ECOQ0FVhoiv16Jgsb2dxHp1M)
if you want to watch the video, please go to this url (https://www.youtube.com/watch?v=qu0IXwi3Fq0) after set subtitled to English (I was in the middle of guys)
Recently, I am personally implementing to Rest-Api Endpoint as test projects using python, flask/fastapi(https://github.com/euiyounghwang/python-fastapi-vector-search, https://github.com/euiyounghwang/python-flask-connexion-example-openapi3-master), and nestjs(https://github.com/euiyounghwang/nest-js-rest-api). The service allows you to search from a search engine (elasticsearch) and Postgres. It is also implemented based on Docker, and is being built, executed, and tested. Also I am interested with similary search such as huggingface embedding, vectorized search using Faiss and so on. (https://github.com/euiyounghwang/semantic-search-elasticsearch-openai-langchain)
components:
schemas:
..
Search:
type: object
properties:
query_string:
type: string
description: Full text search
default: "Cryptocurrency"
nullable: true
start_date:
type: string
format: date
description: Start date
default: "2021 01-01 00:00:00"
size:
type: integer
description: The number of size
default: 20
sort_order:
type: string
enum:
- DESC
- ASC
include_basic_aggs:
type: boolean
description: Flag to enable/disabled aggregations which can slow down queries
pit_id:
type: string
format: date
description: pit_id
example: ""
ids_filter:
type: array
items:
type: string
default: ["*"]
..
I have set up & tested to monitor with alert throught slack such as search engines, restapi endpoints and other application’s metrics using prometheus, alertmanager and grafana. Elasticsearch Prometheus Exporter is a builtin exporter from Elasticsearch to Prometheus. It collects all relevant metrics and makes them available to Prometheus via the Elasticsearch REST API. This is an open source project - Cluster status, Node Status such as JVM, Indices, Circuit Breaker : the feature to prevent OOM occurrence
alerting: alertmanagers:
rule_files:
# My local environment to install node-exporter Docker instance
# docker run --rm -p 9100:9100 prom/node-exporter
# docker compose up -d node-exporter
node_exporter:
# http://localhost:9100/metrics
image: prom/node-exporter
container_name: node_exporter
depends_on:
- prometheus
restart: always
ports:
- 9100:9100
/opt/homebrew/opt/rabbitmq/sbin/rabbitmq-plugins enable rabbitmq_prometheus brew services restart rabbitmq
elasticsearch_exporter plugin
...
# HELP es_jvm_mem_heap_max_bytes Maximum used memory in heap
# TYPE es_jvm_mem_heap_max_bytes gauge
es_jvm_mem_heap_max_bytes{cluster="es-docker-cluster",node="es01",nodeid="ENbXGy5ASPevQ3A5MPnZJg",} 1.073741824E9
# HELP es_index_indexing_delete_current_number Current rate of documents deleted
# TYPE es_index_indexing_delete_current_number gauge
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana_1",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".security-7",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".apm-custom-link",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".security-7",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana_task_manager_1",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index="test_omnisearch_v2",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana_1",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana-event-log-7.9.0-000001",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".apm-agent-configuration",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".apm-custom-link",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana-event-log-7.9.0-000001",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".apm-agent-configuration",context="primaries",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index=".kibana_task_manager_1",context="total",} 0.0
es_index_indexing_delete_current_number{cluster="es-docker-cluster",index="test_omnisearch_v2",context="primaries",} 0.0
# HELP es_index_recovery_current_number Current number of recoveries
...
http://localhost:8081/metrics
...
# TYPE flask_exporter_info gauge
flask_exporter_info{version="0.22.4"} 1.0
# HELP flask_http_request_duration_seconds Flask HTTP request duration in seconds
# TYPE flask_http_request_duration_seconds histogram
flask_http_request_duration_seconds_bucket{le="0.005",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.01",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.025",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.05",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.075",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.1",method="POST",path="/v1/basic/search",status="200"} 0.0
flask_http_request_duration_seconds_bucket{le="0.25",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="0.5",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="0.75",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="1.0",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="2.5",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="5.0",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="7.5",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="10.0",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_bucket{le="+Inf",method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_count{method="POST",path="/v1/basic/search",status="200"} 1.0
flask_http_request_duration_seconds_sum{method="POST",path="/v1/basic/search",status="200"} 0.11475991699990118
...
wget https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-8.8.0-linux-arm64.tar.gz
tar -zxvf metricbeat-8.8.0-linux-arm64.tar.gz
cd metricbeat-8.8.0-linux-arm64/
./metricbeat setup -e
./metricbeat -e
{"find": "terms", "field": "host.name"}
/usr/local/bin/metricbeat -e –path.home=/home/devuser/ES/metricbeat-8.8.0-linux-arm64
– sudo vi /etc/systemd/system/metricbeat.service
[Unit] Description=Metricbeat Service After=multi-user.target
[Service] Type=simple User=devuser Group=devuser WorkingDirectory=/home/devuser/ES/metricbeat-8.8.0-linux-arm64 #ExecStart=/home/devuser/ES/metricbeat-8.8.0-linux-arm64b/start_metricbeat.sh ExecStart=/usr/local/bin/metricbeat -e –path.home=/home/devuser/ES/metricbeat-8.8.0-linux-arm64 Restart=on-failure
[Install] WantedBy=multi-user.target
– Service Registry sudo systemctl daemon-reload
sudo systemctl enable metricbeat.service
sudo systemctl start metricbeat.service sudo systemctl status metricbeat.service
– Log check journalctl -u metricbeat.service ```