<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jack Tanaraksak on Medium]]></title>
        <description><![CDATA[Stories by Jack Tanaraksak on Medium]]></description>
        <link>https://medium.com/@jackchawanwit?source=rss-7f60902f5fdd------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*dLuRzOuoHtEeN0GVOgdK3w.gif</url>
            <title>Stories by Jack Tanaraksak on Medium</title>
            <link>https://medium.com/@jackchawanwit?source=rss-7f60902f5fdd------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 16:27:43 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jackchawanwit/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[[Memo/Tips]การใช้งาน Data source ที่เป็น PostgreSQL ใน OpenMetadata]]></title>
            <link>https://medium.com/@jackchawanwit/memo-tips-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%87%E0%B8%B2%E0%B8%99-data-source-%E0%B8%97%E0%B8%B5%E0%B9%88%E0%B9%80%E0%B8%9B%E0%B9%87%E0%B8%99-postgresql-%E0%B9%83%E0%B8%99-openmetadata-7af4b29c4530?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/7af4b29c4530</guid>
            <category><![CDATA[data]]></category>
            <category><![CDATA[metadata-management]]></category>
            <category><![CDATA[open-metadata]]></category>
            <category><![CDATA[data-observability]]></category>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Mon, 23 Dec 2024 10:38:53 GMT</pubDate>
            <atom:updated>2024-12-23T10:38:53.435Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/651/1*7h1jaxHlITGKEzQUmwB-Ew.png" /><figcaption>Open Metadata</figcaption></figure><p>ในการใช้งาน OpenMetadata ในกรณีที่ data source ของเราเป็น Database PostgreSQL เราจะต้องทำการตรวจสอบการติดตั้ง extension ที่มีชื่อว่า “pg_stat_statements” ก่อนเสมอก่อนที่จะทำการสร้าง service และ ingestion</p><blockquote><strong>pg_stat_statements</strong> <em>เป็น PostgreSQL extension ที่ใช้มอนิเตอร์และตรวจสอบการใช้งาน Query ใน Database โดยหน้าที่จะเก็บ query ทั้งหมดที่ถูกเรียกใช้รวมถึง<br>บันทึกเวลาในการประมวลผลและทรัพยากรที่ใช้ของ query แต่ละตัว</em></blockquote><p>โดยสามารถตรวจสอบได้จากการใช้คำสั่ง sql</p><pre>SELECT * FROM pg_available_extensions WHERE name = &#39;pg_stat_statements&#39;;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3LrFllA9JojN7VXVJ0cHsw.png" /><figcaption>run query ตรวจสอบ pg_stat_statements ผ่าน DBeaver หากพบจะขึ้นผลลัพธ์ตามภาพ</figcaption></figure><p>หากพบว่ายังไม่มีการติดตั้งสามารถใช้คำสั่งต่อไปนี้ได้เลยเพื่อเพิ่มตัว pg_stat_statements ไปยัง database</p><pre>CREATE EXTENSION IF NOT EXISTS pg_stat_statements;</pre><p>และทำการตั้งค่า Privileges</p><pre>GRANT SELECT ON pg_stat_statements TO public; #-- หรือแทน public ด้วย role/user</pre><p>และในตอนสร้าง ingestion metadata หากไม่ต้องการเห็นข้อมูลในส่วนของ pg_stat_statements ที่อาจจะปะปนเข้ามากับตัว data source ที่จะใช้งานให้เราทำการ exclude ตัว table ที่เป็นของระบบซึ่งจะขึ้นต้นด้วย “pg_stat_statements”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/428/1*uT3DsddyNbd6Owl_4lQIjw.png" /><figcaption>filter exclude ตัว table ที่มีคำว่า “pg_stat_statements” อยู่ในชื่อ table</figcaption></figure><blockquote><em>หากทำการ ingestion แล้วพบ schema ที่ชื่อว่า information_schema ตัว </em><strong><em>information_schema</em></strong><em> เป็น system schema ทำหน้าที่เป็นแหล่งข้อมูล Metadata ของฐานข้อมูล โดยช่วยดึงข้อมูลเกี่ยวกับโครงสร้าง schema, table, column, และอื่น ๆ</em></blockquote><blockquote><em>หรือหากเรามีปัญหาหรือข้อสงสัยในการใช้งานสามารถ join เข้าไปยัง Slack ของ OpenMetadata เพื่อสอบถามการใช้งานได้เลยยย </em><a href="https://slack.open-metadata.org/"><em>https://slack.open-metadata.org/</em></a></blockquote><p><strong>ผู้เขียนใช้งาน Openmetadata Version 2.5.13</strong></p><p><strong>Reference</strong></p><ul><li><a href="https://open-metadata.org/">OpenMetadata: The Best Open Source Data Catalog Solution</a></li><li><a href="https://docs.open-metadata.org/latest/connectors/database/postgres">Postgres</a></li><li><a href="https://www.restack.io/docs/openmetadata-knowledge-extract-openmetadata-metadata">Extracting OpenMetadata Product Info</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7af4b29c4530" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[มาทำAutomate deploy python Library ขึ้น PyPI แบบง่ายๆกัน]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%A1%E0%B8%B2%E0%B8%97%E0%B8%B3automate-deploy-python-library-%E0%B8%82%E0%B8%B6%E0%B9%89%E0%B8%99-pypi-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B9%86%E0%B8%81%E0%B8%B1%E0%B8%99-5a60ace3510d?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/5a60ace3510d</guid>
            <category><![CDATA[pypi]]></category>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[python-libraries]]></category>
            <category><![CDATA[python-programming]]></category>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Tue, 08 Oct 2024 08:22:20 GMT</pubDate>
            <atom:updated>2024-10-08T08:22:20.027Z</atom:updated>
            <content:encoded><![CDATA[<p>จากบทความเดิมที่เป็นการอธิบายขั้นตอนการนำ library ของเราขึ้นไปไว้ที่ TestPyPI ซึ่งยังคงเป็นวิธีแบบ manual ผ่าน tool</p><p><a href="https://medium.com/@jackchawanwit/%E0%B8%A1%E0%B8%B2%E0%B8%97%E0%B8%B3-python-library-%E0%B8%82%E0%B8%B6%E0%B9%89%E0%B8%99-pypi-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B9%86%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B9%80%E0%B8%96%E0%B8%AD%E0%B8%B0-41fc243c6816">มาทำ Python Library ขึ้น PyPI แบบง่ายๆกันเถอะ</a></p><p>ในบทความนี้เราจะมาทำ CI/CD automate deploy สำหรับการนำ python library ขึ้นไปบน TestPyPI เพียงแค่เรา comit และ push source code ไปที่ github ก็จะทำการ publish ขึ้นไปที่ TestPyPI แบบอัตโนมัติ</p><p>สิ่งที่เราต้องเตรียมในรอบนี้ก็จะมี</p><ol><li>Python code ที่เราต้องการจะ publish ขึ้นไปไว้ที่ PyPI</li><li>account ของ TestPyPI ที่มีการยืนยันตัวตนเรียบร้อยแล้ว</li><li>API Token ของ TestPyPI ที่เราได้จากรอบที่แล้ว</li><li>account ของ Github</li><li>Repository ใน Github ที่เอาไว้เก็บ Python code ของเรา</li></ol><blockquote>**หากเราจำ API Token ไม่ได้สามารถสร้างใหม่และกำหนด scope ให้ชี้มาที่ package ของเราได้</blockquote><p>ในการทำ CI/CD ครั้งนี้เราจะใช้เครื่องมือ Github Actions ซึ่งเป็นแพลตฟอร์มการทำงานอัตโนมัติที่ช่วยให้เราสร้าง <strong>workflow</strong> ทำงานต่าง ๆ แบบโดยอัตโนมัติเมื่อมีการเปลี่ยนแปลงใน repository เช่น การรันทดสอบโค้ด, การ build, การ deploy, และการตรวจสอบโค้ด โดย GitHub Actions มีความยืดหยุ่นและสามารถปรับแต่งได้ตามต้องการผ่านการใช้ไฟล์ <strong>workflow</strong> ในรูปแบบ YAML ซึ่งถูกเก็บไว้ในโฟลเดอร์ .github/workflows/ ของ repository ที่เราสร้าง</p><p>เตรียม API Token</p><p>โดยเราจะทำการประกาศตัวแปรสำหรับเรียกใช้งาน API Token ของ TestPyPI ใน repository ของเราให้ไปที่เมนู Setting -&gt; Secrets and variables จากนั้นเลือก new repository secret และนำ API Token ที่เรามีไปเก็บไว้ใน Secret</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZLcT2Cn-5izB5LohlC0a_g.png" /><figcaption>ทำการสร้างตัวแปรสำหรับใช้ API Token</figcaption></figure><p>ตั้งค่า Permissions ให้ Workflow</p><p>ไปที่เมนู Settings -&gt; Actions -&gt; general</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-SWickk5KeC63GOTAdnadQ.png" /><figcaption>เมนู Settings-&gt;Actions</figcaption></figure><p>จากนั้นไปที่ Workflow permissions และทำการเลือก <strong>Read and write permissions</strong> จากนั้นทำการ save ได้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*C86XV8EKG_-sVlA7ETZGeA.png" /></figure><p>จากนั้นไปที่เมนู Actions -&gt; new workflow</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lBB1HpnmM31His56MS_OvA.png" /><figcaption>ค้นหา pypi จะเจอ workflow สำเร็จรูปที่มีอยู่แล้ว</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O4X7xyMSXiQ0Mwwax65moA.png" /></figure><p>หลังจากนั้นทำการ commit changes เพื่อเพิ่มไฟล์ workflow เข้าไปที่ repository ของเรา</p><p>ทีนี้เราจะปรับการทำงานของ workflow กันโดยจะให้มีการ trigger ทุกครั้งที่มีการ push code ขึ้นมาที่ branch “main” และทำการ deploy ขึ้นไปที่ TestPyPI</p><p>ไปที่ไฟล์ python-publish.yml ที่อยู่ใน &lt;ชื่อ repository&gt;/<a href="https://github.com/ChawanwitDdata/jack_sayhello/tree/main/.github">.github</a>/<a href="https://github.com/ChawanwitDdata/jack_sayhello/tree/main/.github/workflows">workflows</a> แล้วให้สังเกตุ code ตรง</p><pre>on:<br>  release:<br>    types: [published]</pre><p>ให้ทำการปรับใหม่เป็น</p><pre>on:<br>  push:<br>    branches:<br>      - main</pre><p>เท่านี้เราก็จะได้ trigger ที่ workflow จะเริ่มทำงานเมื่อมีการ push code เข้ามาที่ branch main แล้วจากนั้นทำการแก้ไขการเรียกใช้งาน API Token และปลายทางให้ชี้ไปที่ TestPypi ให้เราไปดู code ตรงส่วนนี้</p><pre>with:<br>        user: __token__<br>        password: ${{ secrets.PYPI_API_TOKEN }}</pre><p>ให้ทำการปรับเป็น</p><pre>with:<br>        user: __token__<br>        password: ${{ secrets.TEST_PYPI_API_TOKEN }}<br>        repository_url: https://test.pypi.org/legacy/</pre><p>โดยตรงตัวแปร password จะเป็นการเรียกใช้งานตัวแปร API Token ที่เราได้ประกาศไว้ที่ secret ก่อนหน้านี้ และเพิ่มตัวแปร repository_url เพื่อให้ชี้เป้าหมายไปยัง TestPyPI</p><p>ตอนนี้เราได้เตรียมการเรียบร้อยแล้วมาลองทดสอบการ push code กันเมื่อเราทำการแก้ไขและทำการ push ไปที่ branch main แล้วให้ไปดูที่เมนู Actions จะเห็นได้ว่า workflow ของเราถูกเรียกใช้งานแล้ว</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VIGd3ZLDrcXnkiOdKc0YfA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PBXsDm07jyiU8UZLpO9oxw.png" /><figcaption>รายละเอียดเมื่อทำการ deploy สำเร็จ</figcaption></figure><p>ทีนี้เราเข้าไปตรวจสอบที่ TestPyPI และไปที่ project ของเราจะพบว่า v0.0.3 ขึ้นมาแล้วววววว</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4fAFTeQN8_275NcYl2dl3w.png" /></figure><blockquote>***ข้อสังเกตุ หากเรามีการแก้ไข code และ deploy ไปยัง TestPyPI เราต้องทำการแก้ไขเลข version ที่ไฟล์ pyproject.toml ด้วยหากไม่ปรับ code ที่เราแก้และ push ขึ้นไปจะไม่มีการ deploy ขึ้นไปยัง TestPyPI ตรงจุดนี้เราหากสามารถแยก branch ที่จะใช้ในการ deploy code และ publish ไปยัง TestPyPI ได้เพื่อไม่ให้ส่งผลต่อการแก้ไขและพัฒนา code</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/665/1*DZvKXTM5kRO620CiIYFntQ.png" /><figcaption>แก้ไขเลข version หากต้องการ publish ไปที่ TestPyPI</figcaption></figure><blockquote>เท่านี้เราก็สามารถ <strong>Automate Deploy </strong>ผ่านการ push ไปยัง GitHub ด้วยการใช้เครื่องมืออย่าง <strong>GitHub Actions </strong>สามารถลดข้อผิดพลาดจากการ deploy แบบ manual และทำให้การพัฒนาซอฟต์แวร์ของเรามีความต่อเนื่อง (CI/CD) โดยไม่สะดุดและทำให้สามารถเผยแพร่ library ให้กับผู้ใช้ได้ทันทีโดยไม่ต้องคอยจัดการด้วยตนเอง ช่วยให้เราสามารถมุ่งเน้นไปที่การพัฒนาและปรับปรุงคุณภาพ code ได้มากขึ้น</blockquote><p>อ้างอิง <a href="https://docs.github.com/en/actions">GitHub Actions document</a></p><blockquote><strong>*** ข้อระวังการใช้งาน GitHub Actions จะมีการจำกัดเวลาไว้ที่ 2000นาทีต่อเดือน</strong></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lCfGe6qRB7pZXRMLqCnJ7Q.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5a60ace3510d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[มาทำ Python Library ขึ้น PyPI แบบง่ายๆกันเถอะ]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%A1%E0%B8%B2%E0%B8%97%E0%B8%B3-python-library-%E0%B8%82%E0%B8%B6%E0%B9%89%E0%B8%99-pypi-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%87%E0%B9%88%E0%B8%B2%E0%B8%A2%E0%B9%86%E0%B8%81%E0%B8%B1%E0%B8%99%E0%B9%80%E0%B8%96%E0%B8%AD%E0%B8%B0-41fc243c6816?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/41fc243c6816</guid>
            <category><![CDATA[how-to]]></category>
            <category><![CDATA[python-libraries]]></category>
            <category><![CDATA[python-programming]]></category>
            <category><![CDATA[pypi]]></category>
            <category><![CDATA[python]]></category>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Wed, 02 Oct 2024 06:21:46 GMT</pubDate>
            <atom:updated>2024-10-02T06:21:46.370Z</atom:updated>
            <content:encoded><![CDATA[<p>การนำ Python library ที่เราเขียนขึ้นมาขึ้นไปไวบน <strong>PyPI</strong> ช่วยให้เราสามารถแบ่งปันโค้ดของเรากับนักพัฒนาทั่วโลกนำไปใช้ได้ และทำให้การติดตั้งโค้ดผ่าน pip เป็นเรื่องง่าย ในบทความนี้จะเป็นอธิบายขั้นตอนในการสร้างและเผยแพร่ Python package ไปยัง PyPI แบบง่ายๆ</p><blockquote><strong>PyPI</strong> (Python Package Index) คือ <strong>repository</strong> หรือแหล่งเก็บแพ็กเกจของ Python ที่ใช้สำหรับการจัดเก็บและเผยแพร่ไลบรารี Python ให้ผู้ใช้งานอื่นๆ สามารถดาวน์โหลดและติดตั้งผ่านเครื่องมืออย่าง pip</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/320/0*BOpwY_Grvp4Ze8dE.png" /><figcaption>PyPI</figcaption></figure><blockquote>โดยในบทความนี้เราจะทำการ publish ขึ้นไปไว้ที่ <a href="http://test.pypi.org/"><strong>TestPyPI</strong></a><strong> </strong>ซึ่งจะเป็นอีก instance หนึ่งแยกกับ <a href="https://pypi.org/">PyPI</a> ทำให้เราสามารถทดสอบการเผยแพร่ได้โดยไม่ส่งผลกระทบต่อ PyPI หลัก</blockquote><p>สิ่งที่เราต้องเตรียมไว้ก่อนเลยก็จะมี</p><ol><li>Python code ที่เราต้องการจะ publish ขึ้นไปไว้ที่ PyPI</li><li>account ของ TestPyPI ที่มีการยืนยันตัวตนเรียบร้อยแล้ว</li><li>เครื่องมือที่จำเป็น pip</li></ol><p>สร้างโครงสร้างของ directory Python โดยจะมีหน้าตาแบบนี้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/501/1*WCJAn6H-tDKll71FdD0DTQ.png" /><figcaption>ภาพโครงสร้างของ python อ้างอิงเอกสาร <a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/">Packaging Python Projects</a></figcaption></figure><p>ทีนี้เราจะมาดูไฟล์ที่สำคัญและจำเป็นต้องมีแต่ละส่วนในโครงสร้าง package ทำหน้าที่อะไรบ้าง:</p><ul><li><strong>__init__.py</strong>: บอกว่าโฟลเดอร์เป็น Python package</li><li><strong>README.md</strong>: เอกสารอธิบายข้อมูลเกี่ยวกับแพ็กเกจ</li><li><strong>LICENSE</strong>: ใบอนุญาตที่ใช้สำหรับ library ของเรา</li><li><strong>pyproject.toml</strong>: ใช้สำหรับการตั้งค่า build system</li><li><strong>tests/</strong> : ใช้สำหรับเก็บไฟล์ test ตอนนี้เราปล่อยว่างไว้ก่อน</li><li><strong>example.py</strong> : เป็นไฟล์ python ที่เราเขียนไว้</li></ul><h3>เลือกเครื่องมือสำหรับ build backend</h3><p>โดยตามเอกสาร official จะมีการระบุเครื่องมือไว้ทั้งหมด4ตัวได้แก่ <a href="https://packaging.python.org/en/latest/key_projects/#hatch"><strong>Hatchling</strong></a>, <a href="https://packaging.python.org/en/latest/key_projects/#setuptools"><strong>Setuptools</strong></a><strong> </strong>, <a href="https://packaging.python.org/en/latest/key_projects/#flit"><strong>Flit</strong></a> และ <a href="https://packaging.python.org/en/latest/key_projects/#pdm"><strong>PDM</strong></a> โดยแต่ละตัวมีจุดประสงค์คล้ายกัน แต่มีความแตกต่างกันในด้าน ความยืดหยุ่น และวิธีการใช้งาน ซึ่งตัวที่เราเลือกใช้งานคือตัว <strong>Hatchling </strong>ที่มีการใช้งานง่าย และเหมาะกับ project เล็กที่ไม่ซับซ้อนมากโดยจะมีการเรียกใช้แบบนี้</p><pre>[build-system]<br>requires = [&quot;hatchling&quot;]<br>build-backend = &quot;hatchling.build&quot;</pre><p>โดยจะนำไปใส่ในไฟล์ pyproject.tomlที่จะอธิบายในขั้นตอนต่อไป</p><h3>การตั้งค่าไฟล์ pyproject.toml</h3><p>จากนั้นเราจะทำการแก้ไขไฟล์ pyproject.toml โดยจะประกอบไปด้วย</p><pre>[build-system]<br>requires = [&quot;hatchling&quot;]<br>build-backend = &quot;hatchling.build&quot;<br><br>[project]<br>name = &quot;ชื่อ package ของเรา&quot;<br>version = &quot;0.0.1&quot;<br>authors = [<br>  { name=&quot;ชื่อเจ้าของ&quot;, email=&quot;author@example.com&quot; },<br>]<br>description = &quot;อธิบายรายละเอียดของ package เรา&quot;<br>readme = &quot;README.md&quot;<br>requires-python = &quot;&gt;=3.8&quot;<br>classifiers = [<br>    &quot;Programming Language :: Python :: 3&quot;,<br>    &quot;License :: OSI Approved :: MIT License&quot;,<br>    &quot;Operating System :: OS Independent&quot;,<br>]<br><br>[project.urls]<br>Homepage = &quot;https://github.com/pypa/sampleproject&quot;<br>Issues = &quot;https://github.com/pypa/sampleproject/issues&quot;</pre><ul><li>name ชื่อ package ของเรา ซึ่งอาจเป็นชื่อใดก็ได้ แต่ต้องไม่มีชื่อแพ็กเกจนี้อยู่ใน PyPI อยู่แล้ว</li><li>version เป็นการกำหนด version ของ package เรา หรืออาจจะมีการกำหนดมาจากส่วนอื่นในกรณีที่เรามีการใช้ git</li><li>authors ข้อมูลเจ้าของ package โดยจะมีระบุชื่อกับ email ของเราลงไป</li><li>description อธิบายข้อมูล package ของเรา</li><li>readme เป็นค่า path ของไฟล์ README.md ที่เป็นไฟล์เก็บข้อมูลรายละเอียดเกี่ยวกับ package ของเรา</li><li>requires-python ความต้องการ version ขั้นต่ำของ python ที่ต้องการในการติดตั้ง package ของเรา</li><li>classifiers เป็นการจัดหมวดหมู่ของ package เช่น สถานะของ package , ระบบปฏิบัติการที่รองรับ, เวอร์ชัน Python ที่รองรับ, ประเภทของซอฟต์แวร์ โดยสามารถดูรายการหมวดหมู่ได้จากเอกสารนี้ <a href="https://pypi.org/classifiers/">List of classifiers</a></li><li>urls รายการ link url เพิ่มเติมเกี่ยวกับ เอกสารประกอบ ที่มาสำหรับแสดงบน PyPI</li></ul><h3>สร้าง README.md</h3><p>ระบุข้อมูลรายละเอียดของ package เรา</p><pre># Example Package<br><br>This is a simple example package.<br></pre><h3>กำหนด LICENSE</h3><p>จากนั้นเราก็ต้องทำการกำหนด LICENSE เพื่อเป็นการบอกว่า library ของเรานั้นอนุญาตให้ให้ใช้ library ของเราทำอะไรได้บ้างและใช้โดยใคร ซึ่งตัว license เราสามารถไปดูข้อมูลเพิ่มเติมได้จาก <a href="https://choosealicense.com/">choosealicense</a></p><h3>การ build package</h3><p>เมื่อเราได้กำหนดค่าไฟล์ต่างๆเรียบร้อย รวมถึงไฟล์ python ของเราเองพร้อมให้คนอื่นนำไปใช้งานแล้วในขั้นตอนต่อไปจะเป็น ทำการติดตั้งเครื่องมือที่ใช้สำหรับการ <strong>build Python packages </strong>โดยใช้คำสั่งตามนี้ได้เลย</p><pre>py -m pip install --upgrade build</pre><p>ทำการ run คำสั่ง build โดยก่อน run ให้ตรวจสอบที่อยู่ directory ก่อนจะ run ว่าต้องอยู่ใน directory เดียวกับไฟล์ pyproject.toml ด้วย</p><pre>py -m build</pre><p>หาก build สำเร็จเราจะได้ไฟล์มาอยู่ใน directory dist/ ซึ่งจะมี 2 ตัวได้แก่ไฟล์นามสกุล .whl และ .tar.gz</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/635/1*7yPYfb2pYQ2BqDf-NQDnyA.png" /><figcaption>ตัวอย่างไฟล์ที่ได้หลังจาก build สำเร็จ</figcaption></figure><blockquote>.whl (wheel) เป็นไฟล์ที่ถูก build และพร้อมใช้งานแล้ว ซึ่งทำให้ pip สามารถติดตั้ง package ได้เลยโดยไม่ต้อง build package ขึ้นใหม่</blockquote><blockquote>.tar.gz เป็นไฟล์ที่ประกอบไปด้วย source code ของ package และจะต้องถูก build ขึ้นใหม่เมื่อมีการติดตั้งโดย pip</blockquote><h3>สร้าง API Token</h3><p>เมื่อเรามี account ของ TestPyPI ที่มีการยืนยันตัวตนเรียบร้อยแล้วให้ทำการสร้าง API Token ผ่านเมนู Account Setting โดยทำการกำหนดชื่อ project และ scope การใช้งาน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oOSBZ_FoUpP8eoOSYaWTmA.png" /><figcaption>หน้าต่างสร้าง API Token ในเมนู Account setting</figcaption></figure><h3>เริ่ม Upload Package</h3><p>ก่อนอื่นเราทำการติดตั้ง twine สำหรับใช้ในการ upload package ของเราขึ้นไปยัง TestPyPI</p><pre>py -m pip install --upgrade twine</pre><blockquote><strong>Twine</strong> เป็นเครื่องมือที่ใช้สำหรับอัปโหลด Python packages ขึ้นไปยัง <strong>PyPI</strong> หรือ <strong>TestPyPI </strong>ได้อย่างปลอดภัย โดยผ่าน HTTPS</blockquote><p>หลังจากติดตั้ง twine เรียบร้อยแล้วเราจะมาทำการ upload package ของเราขึ้นไปยัง <strong>TestPyPI </strong>ก่อนอื่นเลยให้เราทำการตรวจสอบไฟล์ package<strong> </strong>โดยการใช้คำสั่ง</p><pre>python3 -m twine check dist/*</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/488/1*Gf5In6HpSKtDTs1cIXKniA.png" /></figure><p>หากขึ้น passed แปลว่าพร้อม upload แล้วให้ทำการ upload ได้เลย</p><pre>py -m twine upload --repository testpypi dist/*</pre><p>จากคำสั่งที่ run ไปจะเป็นการนำไฟล์ที่ผ่านการ build แล้วใน folder dist/ upload ขึ้นไปที่ repository testpypi และจะมีการถามหาตัว API Token ที่เราได้ทำการสร้างไว้ก่อนหน้านี้ให้ทำการ copy แล้ว past ไปที่ terminal ได้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*BDzCYu9XAFdvI3mS9BFziQ.png" /></figure><p>เมื่อเรา upload สำเร็จแล้วที่เมนู your projects จะปรากฏ package ที่เราได้ทำการ upload ไปดังภาพ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*msrhUhmusDE12IZS-qVsuQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vZr1BTVh_pCVZhE9qjtrLA.png" /></figure><p>ตอนนี้ Library ของเราสามารถใช้งานผ่าน pip ได้แล้ว โดยสามารถ copy คำสั่ง pip install แล้วลอง import ใช้งานกันได้เลย</p><blockquote>หากต้องการ publish ขึ้น PyPI ปกติสามารถใช้วิธีตามนี้ได้เพียงแค่เปลี่ยน repository จาก TestPyPI ไปเป็น PyPI โดย account ของ PyPI ปกติจะแยกกับ TestPyPI เราต้องไปสมัครและยืนยันตัวตนใหม่อีกรอบ</blockquote><pre>py -m twine upload dist/*<br>รวมถึงตอนใช้งาน twine upload ไม่จำเป็นต้องใช้ --repository <br>ต่อท้าย เนื่องจากมีค่า default เป็น pypi อยู่แล้ว<br></pre><blockquote>การสร้างและเผยแพร่ Python library ขึ้นไปยัง PyPI ไม่ใช่เรื่องที่ยากอย่างที่คิด หากเราทำตามขั้นตอนที่ถูกต้อง ไม่ว่าจะเป็นการเตรียมโครงสร้าง package การเขียนไฟล์ตั้งค่า และการอัปโหลดไปยัง PyPI โดยเครื่องมืออย่าง twine จะช่วยให้เราสามารถทำทุกขั้นตอนได้อย่างเป็นระบบ</blockquote><blockquote>การเผยแพร่ library ของเราบน PyPI ไม่เพียงแค่ช่วยให้เราสามารถแบ่งปันโค้ดให้กับคนอื่นๆ ได้ใช้งาน แต่ยังช่วยให้library ของเราได้มีการปรับปรุงและพัฒนา จากการช่วยกันของชุมชนผู้ใช้งาน นอกจากนี้ การมีเอกสารรายละเอียดการใช้งานที่ชัดเจนและการปรับปรุงอย่างสม่ำเสมอจะช่วยให้ library ของเรามีคุณภาพและได้รับความนิยมใช้งานมากขึ้น</blockquote><blockquote>ดังนั้น หากเรามี library หรือ code ที่น่าสนใจ อย่ารอช้าลองนำขึ้นไปที่ PyPI แล้วแบ่งปันให้กับชุมชนผู้ใช้งาน Python ได้ใช้งานกันเถอะ!</blockquote><blockquote>อ้างอิง <a href="https://packaging.python.org/en/latest/tutorials/packaging-projects/">Python Packaging User Guide</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=41fc243c6816" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก]Install CDP on CentOS7]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-install-cdp-on-centos7-62e09fd38512?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/62e09fd38512</guid>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Sat, 04 Nov 2023 16:01:48 GMT</pubDate>
            <atom:updated>2023-11-04T16:01:48.714Z</atom:updated>
            <content:encoded><![CDATA[<p>require</p><ul><li>เครื่องที่ติดตั้ง CentOS7 ไว้</li><li>Cloudera account with licence(ถ้ามีหากไม่มีจะใช้เป็นแบบ trial แทน)</li><li>Java open jdk</li><li>python</li><li>Database for config (PostgreSQL)+user to access</li></ul><p>ก่อนจะทำการติดตั้งให้ทำการตรวจสอบ version ของเครื่องมือต่างๆที่จะใช้ได้ใน <a href="https://supportmatrix.cloudera.com/">https://supportmatrix.cloudera.com/</a></p><h3>Step 1. Config repository for cloudera manager ( version. 7.9.5 )</h3><p>เข้าไปยัง directory /etc/yum.repos.d/ แล้วใช้คำสั่ง</p><pre>sudo wget https://[username]:[password]@archive.cloudera.com/p/cm7/[**Cloudera Manager version**]/redhat8/yum/cloudera-manager.repo</pre><p>หลังจากนั้นทำการ Import the repository signing GPG key โดยใช้คำสั่ง</p><pre>sudo rpm --import https://[username]:[password]@archive.cloudera.com/p/cm7/[**Cloudera Manager version**]/redhat7/yum/RPM-GPG-KEY-cloudera</pre><h3>Step 2. ติดตั้ง java</h3><p>ทำการติดตั้ง java โดยใช้คำสั่ง</p><pre>yum install java-1.8.0-openjdk-devel</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NQUtD_QK2dX4bh6DXmy7rw.png" /></figure><h3>Step 3. ติดตั้ง Cloudera Manager Server</h3><p>ติดตั้ง Cloudera manager server โดยใช้คำสั่ง</p><pre>yum install cloudera-manager-daemons cloudera-manager-agent cloudera-manager-server</pre><h3>Step 4. ติดตั้ง Python สำหรับ hue</h3><p>ทำการติดตั้ง package</p><ul><li>openssl-devel</li><li>bzip2-devel</li><li>libffi-devel</li><li>zlib-devel</li></ul><pre>yum install gcc openssl-devel bzip2-devel libffi-devel zlib-devel -y</pre><p>หลังจาก install package เสร็จเรียบร้อยแล้วจะทำการติดตั้ง python ต่อโดยให้ย้าย directory ไปที่ opt โดยใช้คำสั่ง</p><pre>cd /opt</pre><p>จากนั้นทำการ download python โดยใช้คำสั่ง</p><pre>curl -O https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz</pre><p>แล้วทำการแตกไฟล์ด้วยคำสั่ง</p><pre>tar -zxvf Python-3.8.12.tgz</pre><p>หลังจากแตกไฟล์เรียบร้อยให้เข้าไปใน folder โดยใช้คำสั่ง</p><pre>cd Python-3.8.12</pre><p>จากนั้นใช้คำสั่งดังต่อไปนี้เพื่อติดตั้ง python</p><pre>./configure --enable-shared</pre><p>หลังจากติดตั้งเรียบร้อยแล้วทำการ compile file ต่อโดยใช้คำสั่ง</p><pre>make</pre><p>จากนั้นใช้คำสั่ง</p><pre>make install</pre><p>คัดลอกไฟล์ libpython3.8.so ไปไว้ใน /lib64/ โดยใช้คำสั่ง</p><pre>cp --no-clobber ./libpython3.8.so* /lib64/</pre><p>ทำการปรับ permission file โดยใช้คำสั่ง</p><pre>chmod 755 /lib64/libpython3.8.so*</pre><p>และ</p><pre>chmod -R 755 /usr/local/lib/python3.8</pre><h3>Step 5. ติดตั้ง Database สำหรับ config</h3><p>โดยจะรองรับ PostgreSQL , MySQL , MariaDB , Oracle Database โดยในการติดตั้งครั้งนี้จะเลือกใช้ PostgreSQL สำหรับใช้งานกับ cloudera</p><p>เริ่มจากทำการติดตั้ง postgresql-server โดยใช้คำสั่ง</p><pre>sudo yum install postgresql-server</pre><p>จากนั้นทำการติดตั้ง Postgres JDBC Driver โดยทำการตรวจสอบ version ของ driver ได้จาก <a href="https://jdbc.postgresql.org/">https://jdbc.postgresql.org/</a> และใช้คำสั่ง</p><pre>yum install postgresql-jdbc&lt;compatible_version&gt;</pre><p>ทำการ update yum อีกรอบ</p><pre>yum update</pre><p>และทำการเปลี่ยนชื่อไฟล์ driver และย้ายตำแหน่งไฟล์โดยใช้คำสั่ง</p><pre>cp /usr/share/java/postgresql-jdbc.jar /usr/share/java/postgresql-connector-java.jar</pre><p>ตรวจสอบไฟล์ .jar โดยใช้คำสั่ง</p><pre>ls /usr/share/java/postgresql-connector-java.jar </pre><p>ปรับ permission ของไฟล์ .jar โดยใช้คำสั่ง</p><pre>chmod 644 /usr/share/java/postgresql-connector-java.jar</pre><p>จากนั้นจะทำการ install psycopg2 Python package สำหรับ PostgreSQL-backed Hue</p><p>โดยให้ไปที่ directory ที่มีการติดตั้ง cloudera-manager.repo ไว้ ( ซึ่งในการลงครั้งนี้ไฟล์จะอยู่ที่ /etc/yum.repo.d ) จากนั้นทำการแก้ไขไฟล์โดยใช้คำสั่ง</p><pre>nano cloudera-manager.repo</pre><p>โดยในไฟล์ config ของ cloudera-manager.repo จะมีการเพิ่มค่าไปดังนี้</p><pre>[postgresql10]<br>name=Postgresql 10<br>baseurl=https://archive.cloudera.com/postgresql10/redhat8/<br>gpgkey=https://archive.cloudera.com/postgresql10/redhat8/RPM-GPG-KEY-PGDG-10<br>enabled=0 <br>gpgcheck=1<br>module_hotfixes=true </pre><p>ทำการ restart ตัว database</p><pre>sudo systemctl restart postgresql-14</pre><p>สร้าง database config สำหรับตัว cloudera</p><p>ทำการเข้าใช้งาน posgreSQL ด้วยคำสั่ง</p><pre>sudo -u postgres psql</pre><p>สร้าง user สำหรับใช้งานใน database โดยใช้คำสั่ง</p><pre>CREATE ROLE &lt;user&gt; LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br><br><br>------------------- ตัวอย่าง ----------------------<br>1.============== Cloudera Manager Server =====<br>CREATE ROLE scm LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>2.============== Reports Manager ====================<br>CREATE ROLE rman LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>3.============== Ranger RHEL/CentOS/Ubuntu ====================<br>CREATE ROLE rangeradmin LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>4.============== Ranger KMS RHEL/CentOS ====================<br>CREATE ROLE rangerkms LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>5.============== Hue ====================<br>CREATE ROLE hue LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>6.============== Hive Metastore Server ====================<br>CREATE ROLE hive LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>7.============== Oozie ====================<br>CREATE ROLE oozie LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>8.============== Data Analytics Studio (DAS) Supported with PostgreSQL only. ====================<br>CREATE ROLE das LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>9.============== Schema Registry ====================<br>CREATE ROLE schemaregistry LOGIN PASSWORD &#39;&lt;password&gt;&#39;;<br><br>10.============== Streams Messaging Manager ====================<br>CREATE ROLE smm LOGIN PASSWORD &#39;&lt;password&gt;&#39;;</pre><p>ทำการสร้าง database ขึ้นมาโดยใช้คำสั่ง</p><pre>CREATE DATABASE &lt;database&gt; OWNER &lt;user&gt; ENCODING &#39;UTF8&#39;;<br><br>------------------- ตัวอย่าง ----------------------<br>1.============== Cloudera Manager Server ====================<br>CREATE DATABASE scm OWNER scm ENCODING &#39;UTF8&#39;;<br><br>2.============== Reports Manager ====================<br>CREATE DATABASE rman OWNER rman ENCODING &#39;UTF8&#39;;<br><br>3.============== Ranger RHEL/CentOS/Ubuntu ====================<br>CREATE DATABASE ranger OWNER rangeradmin ENCODING &#39;UTF8&#39;;<br><br>4.============== Ranger KMS RHEL/CentOS ====================<br>CREATE DATABASE ranger OWNER rangerkms ENCODING &#39;UTF8&#39;;<br><br>5.============== Hue ====================<br>CREATE DATABASE hue OWNER hue ENCODING &#39;UTF8&#39;;<br><br>6.============== Hive Metastore Server ====================<br>CREATE DATABASE hive OWNER hive ENCODING &#39;UTF8&#39;;<br><br>7.============== Oozie ====================<br>CREATE DATABASE oozie OWNER oozie ENCODING &#39;UTF8&#39;;<br><br>8.============== Data Analytics Studio (DAS) Supported with PostgreSQL only. ====================<br>CREATE DATABASE das OWNER das ENCODING &#39;UTF8&#39;;<br><br>9.============== Schema Registry ====================<br>CREATE DATABASE schemaregistry OWNER schemaregistry ENCODING &#39;UTF8&#39;;<br><br>10.============== Streams Messaging Manager ====================<br>CREATE DATABASE smm OWNER smm ENCODING &#39;UTF8&#39;;<br><br></pre><p>สร้างทีละ database ตามตารางด้านล่าง</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/795/1*z3uFGgG5luGw7hTtKq7QAQ.png" /><figcaption>ตาราง database สำหรับ cloudera</figcaption></figure><p>หากมีการใช้งาน PostgreSQL 8.4 หรือใหม่กว่าให้ทำการตั้งค่าตัวแปรของ Hive Metastore และ Oozie ที่ชื่อว่า standard_conforming_strings เป็น off โดยใช้คำสั่ง</p><pre>ALTER DATABASE &lt;database&gt; SET standard_conforming_strings=off;<br><br>========== ตัวอย่าง ==============<br>ALTER DATABASE hive SET standard_conforming_strings=off;<br>ALTER DATABASE Oozie SET standard_conforming_strings=off;<br></pre><h3>Step 6. ตั้งค่า config สำหรับ cloudera manager database</h3><p>ในการตั้งค่า config จะมีไฟล์ script สำหรับ run ที่ชื่อว่า scm_prepare_database.sh โดยการเรียกใช้งานจะใช้คำสั่งดังต่อไปนี้</p><pre>sudo /opt/cloudera/cm/schema/scm_prepare_database.sh [options] &lt;databaseType&gt; &lt;databaseName&gt; &lt;databaseUser&gt; &lt;password&gt;</pre><p>โดยค่า parameter จะประกอบไปด้วย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/837/1*ZAYLfU_Uic6HEwxy7kNhzg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/839/1*wYDz_A1oz-N22owyID_wcQ.png" /></figure><p>ตัวอย่างคำสั่งสำหรับการตั้งค่า config ของ scm service ไปยัง database</p><pre>==== กรณีที่ cloudera manager กับ database config อยู่ภายในเครื่องเดียวกัน ====<br>sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql scm scm<br><br>==== กรณีที่ cloudera manager กับ database config อยู่คนละเครื่อง ====<br>sudo /opt/cloudera/cm/schema/scm_prepare_database.sh mysql -h &lt;ip/host name เครื่อง database&gt; - scm-host &lt;hostname เครื่อง cloudera&gt; scm scm<br><br><br>============== Cloudera Manager Server ====================<br>sudo /opt/cloudera/cm/schema/scm_prepare_database.sh postgresql -h &lt;dbhost&gt; -P 5432 --scm-host &lt;clouderamanager host&gt; scm scm<br><br></pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*qbsG6XeN6zj77iYjEhnDbA.png" /><figcaption>หลังจาก run scm_prepare_database.sh จะได้ผลตามนี้</figcaption></figure><h3>Step 7. start cloudera scm server</h3><p>ก่อนอื่นทำการตรวจสอบ service cloudera-scm-server โดยใช้คำสั่ง</p><pre>sudo systemctl status cloudera-scm-server</pre><p>จากนั้นทำการ start ตัว server ขึ้นมา</p><pre>sudo systemctl start cloudera-scm-server</pre><p>และตั้งค่าให้ตัว server ทำการ start แบบ automatic เมื่อมีการ reboot เครื่องโดยใช้คำสั่ง</p><pre>sudo systemctl enable cloudera-scm-server</pre><p>ทำการตรวจสอบ status server อีกครั้ง</p><pre>sudo systemctl status cloudera-scm-server</pre><p>หลังจาก start server เรียบร้อยแล้วสามารถเข้าใช้งานได้ผ่าน url ตามนี้</p><pre>http://&lt;server_host&gt;:7180<br><br>========Default User &amp; Password สำหรับ login =====<br>Username: admin<br>Password: admin</pre><p>**โดยในการเข้าใช้งานครั้งแรกจะมีหน้าต่างขึ้นมาให้เลือกในส่วนของการใช้งาน แบบมีlicence กับ แบบ trial</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mi6rSfEL27nLW0YS-l0qJg.png" /><figcaption>หน้าจอ login</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fw5d4I_cgc4miWKJ3O7-Qw.png" /><figcaption>หลังจาก login และเลือกรูปแบบการใช้งานแล้วจะเข้าสู่หน้า home ของตัว manager</figcaption></figure><p>**หากต้องการดู log ของตัว server สามารใช้คำสั่ง</p><pre>sudo tail -f /var/log/cloudera-scm-server/cloudera-scm-server.log</pre><p>เพื่อคอยตรวจสอบ error หรือการแจ้งเตือนอาการผิดปกติได้</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=62e09fd38512" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก]การติดตั้ง Apache NiFi]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-apache-nifi-9e94fcaa0f?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/9e94fcaa0f</guid>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Fri, 09 Jun 2023 10:46:17 GMT</pubDate>
            <atom:updated>2023-06-09T10:46:17.930Z</atom:updated>
            <content:encoded><![CDATA[<p>Apache NiFi เป็นแพลตฟอร์ม open source สำหรับการออกแบบและการจัดการprocessของข้อมูลในระบบที่มีความซับซ้อน โดยเฉพาะอย่างยิ่งในระบบที่มีการสื่อสารและการกระจายข้อมูลอย่างหลากหลาย</p><p>Apache NiFi สามารถใช้งานได้ในกรณีการประมวลผลข้อมูลแบบครบวงจร (end-to-end data flow) ซึ่งรวมถึงการเชื่อมต่อและการควบคุมกระบวนการข้อมูล โดยสามารถทำการติดตามสถานะ การควบคุม การจัดเก็บ การกระจายและการประมวลผลข้อมูลได้อย่างง่ายดาย นอกจากนี้ยังสามารถทำงานแบบเรียลไทม์ที่ดีกับการควบคุม การตรวจจับข้อผิดพลาด และการกำหนดข้อกำหนดเพื่อให้ได้ความสามารถในการประมวลผลแบบอัตโนมัติได้</p><h3>Install in centos7</h3><p>โดยในการติดตั้ง Apache NiFi เราจะต้องมีการติดตั้งตัว java พร้อมกับประกาศ JAVA_HOME ให้เรียบร้อยจากนั้นทำการ download ตัว Apache NiFi จาก <a href="https://archive.apache.org/dist/nifi/1.21.0/">https://archive.apache.org/dist/nifi/</a> โดยเลือก version ที่ต้องการติดตั้ง และทำการ download ตัวที่เป็น bin</p><p>โดยจะยกตัวอย่างเป็นการใช้ version 1.21.0 ก็จะ download ไฟล์ตามนี้ <a href="https://archive.apache.org/dist/nifi/1.21.0/nifi-1.21.0-bin.zip">nifi-1.21.0-bin.zip</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*xtuEc4atpXOTgiE9IPIoUg.png" /></figure><p>ทำการตรวจสอบว่าภายในเครื่องเรามีการประกาศ JAVA_HOME ไว้เรียบร้อยแล้วโดยใช้คำสั่ง</p><pre>echo $JAVA_HOME</pre><p>จากนั้นทำการแตกไฟล์ zip ที่download มาโดยใช้คำสั่ง</p><pre>unzip nifi-1.21.0-bin.zip</pre><p>หลังจากที่ทำการแตกไฟล์เรียบร้อยแล้วเราจะได้ folder เพิ่มขึ้นมาโดยให้เราเข้าไปที่ directory bin เพื่อทดสอบ start ตัว Apache NiFi โดยใช้คำสั่ง</p><pre>./nifi.sh start</pre><p>หาก run สำเร็จเราสามารถเข้าในงาน Apache NiFi ได้ผ่าน web browser url</p><pre>https://localhost:8443/nifi/</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hVLosYkykigsJYiZbn4vdw.png" /></figure><p>โดยจะมีค่า port default เป็น 8443</p><p>ในการ login เข้าใช้งานหากเราไม่ได้มีการ set user จะต้องใช้ username และ password จาก log ซึ่งเราสามารถเรียกดู generate username/password สำหรับloginได้จากไฟล์ log nifi-app.log ที่อยู่ใน directory logs จากนั้นใช้คำสั่ง</p><pre>cat nifi-app.log | grep Generated</pre><p>ดังนั้นหากต้องการกำหนด username password สำหรับใช้งานในตอนที่ start ให้เราใช้คำสั่ง</p><pre>nifi.sh set-single-user-credentials &lt;username กำหนดเอง&gt; &lt;password กำหนดเอง&gt;</pre><p>แทนจากเดิมที่เป็นแค่ start ธรรมดา</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9e94fcaa0f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก] การติดตั้งและทดลองใช้งาน Cloudera Streaming Platform]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87%E0%B9%81%E0%B8%A5%E0%B8%B0%E0%B8%97%E0%B8%94%E0%B8%A5%E0%B8%AD%E0%B8%87%E0%B9%83%E0%B8%8A%E0%B9%89%E0%B8%87%E0%B8%B2%E0%B8%99-cloudera-streaming-platform-a11bd8e64f27?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/a11bd8e64f27</guid>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Fri, 28 Apr 2023 07:32:34 GMT</pubDate>
            <atom:updated>2023-04-28T07:32:34.913Z</atom:updated>
            <content:encoded><![CDATA[<p>สิ่งที่ต้องเตรียมก่อนเริ่มติดตั้งและใช้งาน</p><ul><li>Docker Desktop(<a href="https://www.docker.com/products/docker-desktop/">Download</a>)</li><li><a href="https://repo1.maven.org/maven2/io/debezium/debezium-connector-mysql/">Debezium</a> โดยเลือก version ที่ต้องการและ download ไฟล์ debezium-connector-mysql-&lt;version&gt;.Final-plugin.zip</li><li>**หากต้องการทำ sink connector ที่เป็น mysql ต้องใช้ JDBC Driver สำหรับใช้เชื่อมต่อ database ใช้ mysql-connector-java ที่เป็นไฟล์ .jar / .pom (<a href="https://repo1.maven.org/maven2/mysql/mysql-connector-java">download</a>) แต่ภายในบทความจะใช้งาน postgresql เป็น database สำหรับ sink</li></ul><h3>Cloudera CSP คืออะไร</h3><p>Cloudera CSP (Cloudera Streaming Platform) เป็นแพลตฟอร์มการสตรีมข้อมูลแบบองค์รวม (end-to-end streaming platform) ที่ออกแบบมาเพื่อให้ผู้ใช้สามารถสร้างและบริหารจัดการระบบการสตรีมข้อมูลได้อย่างมีประสิทธิภาพและง่ายดาย โดยใช้เทคโนโลยี Apache Flink และ Apache NiFi เป็นหลัก</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/847/0*qwPs9EzaCGXfzNFH.png" /></figure><h3>Step1. ติดตั้ง CSP Community Edition</h3><p>หลังจากที่เราได้ทำการติดตั้ง docker desktop เรียบร้อยแล้ว จะทำการเตรียมไฟล์ docker-compose.yml ของ CSP โดยสามารถ download ได้จาก <a href="https://www.cloudera.com/downloads/cdf/csp-community-edition.html">Downloads Page of CSP Community Edition</a>. จากนั้นสร้าง folder ชื่อ cspce และนำไฟล์ docker-compose.yml ไปไว้ด้านในหลังจากนั้นทำการเปิด terminal หรือ cmd และเข้าไปที่ folder cspce และทำการ run คำสั่ง</p><pre>docker-compose up -d</pre><p>เมื่อติดตั้งเรียบร้อยจะได้ docker container แบบเต็มระบบ โดบหลังจากนี้เราสามารถใช้งานตัว User Interface ผ่าน url ดังต่อไปนี้</p><pre>Schema Registry :            http://localhost:7788<br>Streams Messaging Manager :  http://localhost:9991<br>Streaming SQL Builder:       http://localhost:18121<br>                             Username: admin<br>                             Password: admin<br></pre><h3>Step2. Update debezium version in docker</h3><p>ทำการแตกไฟล์ debezium-connector-mysql-&lt;version&gt;.Final-plugin.zip</p><p>จากนั้นที่ docker desktop ให้เราเข้าไปที่เครื่อง kafka-connect-1 แล้วไปที่แท็บ file</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0v54igl1YDrMNJmMkZ5DJg.png" /></figure><p>และเข้าไปยัง opt/connect/plugin/libs จะพบกับ folder ที่ติดตั้ง debezium ไว้ชื่อว่า debezium-connector-mysql ให้ทำการ delete ทิ้งไปและทำการ import ไฟล์ที่ได้จากการแตกไฟล์เข้าไปวางแทนที่ชื่อเดิมและทำการ restart เครื่อง</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/759/1*E_xF1d-mSevNcF-lcJvbRw.png" /></figure><h3>Step3. create connector and connect to source</h3><p>หลังจากทำการอัพเดท debezium version เรียบร้อยแล้วทำการเข้ามายังหน้า ui ของ Streams Messaging Manager ผ่าน</p><pre>http://localhost:9991</pre><p>และเข้าไปยัง menu connector ไปที่ new connector</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EmSewsx8d4bHkZlomnxiww.png" /></figure><p>แล้วทำการเลือก source template ที่ต้องการสร้าง</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oU9oELKVSNafuRvaaqe1KQ.png" /></figure><p>ระบุการตั้งค่า source database ให้ครบถ้วน</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q6wLh3DytfYO9CeZW-m8AA.png" /></figure><p>หลังจากระบุครบถ้วนแล้วให้ทำการ Validate config ด้วยปุ่ม validate ด้านขวาบนและทำการ next จากนั้นตรวจสอบอีกครั้งจึงทำการ deploy</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*m2dTAn_pEEtfKfu7VJ7nVA.png" /><figcaption>หากเชื่อมต่อสำเร็จจะได้ผลลัพธ์ตามภาพ</figcaption></figure><p>Step4.(optional) create connector for sink</p><p>การสร้าง sink connector จะเหมือนกับการสร้าง source connector โดยในครั้งนี้จะเลือกเป็น เชื่อมต่อไปยัง postgres database</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DpDi6TUp33NIhQ1lWfbfaA.png" /></figure><p>จากนั้นใช้ import connector configuration</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bQcE8Xmon_ngeUpYfrFmBw.png" /></figure><p>ทำการตรวจสอบค่าตัวแปรต่างๆแล้วทำการ validate ก่อนกด next และ deploy</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BvlWNkom5CllCGld1snOTg.png" /><figcaption>หลังจากทำสำเร็จเราจะได้หน้าตา flow แบบนี้</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a11bd8e64f27" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก] Archive logs และ Redo log ใน Oracle Database]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-archive-logs-%E0%B9%81%E0%B8%A5%E0%B8%B0-redo-log-%E0%B9%83%E0%B8%99-oracle-database-fce9146c9669?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/fce9146c9669</guid>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Wed, 29 Mar 2023 06:23:38 GMT</pubDate>
            <atom:updated>2023-03-29T06:23:38.289Z</atom:updated>
            <content:encoded><![CDATA[<h3>Archive logs คืออะไร?</h3><p>Archive logs คือการสร้างสำเนาของ Redo logs และเก็บไว้ในที่เก็บข้อมูลที่แตกต่างจากที่เก็บ Redo logs ปกติ โดยทำการ Archive logs เป็นวิธีการทำ Backup and Recovery ที่มักจะถูกนำมาใช้งานในการกู้ข้อมูลที่สูญหายหรือเสียหาย</p><h3>Redo logs คืออะไร?</h3><p>Redo logs เป็นไฟล์ที่ใช้บันทึกข้อมูลการทำงาน/การกระทำ (transactional data) ที่เกิดขึ้นในฐานข้อมูล โดย Redo logs จะถูกสร้างขึ้นเมื่อมีการกระทำเกี่ยวกับข้อมูลในฐานข้อมูล เช่น เพิ่ม ลบ หรือแก้ไขข้อมูลในตาราง</p><p>Redo logs จะมีการเขียนลงไฟล์แบบ Circular ซึ่งเป็นการเขียนทับข้อมูลเก่าที่มีอยู่ในไฟล์ Redo logs แล้วเมื่อครบรอบการบันทึก</p><p>การใช้ Redo log นั้นมีประโยชน์อย่างมาก เช่น การ Backup and Recovery และช่วยลดความเสี่ยงที่จะสูญเสียข้อมูลในฐานข้อมูลได้</p><h3>Supplemental Logging คืออะไร</h3><p>เป็นการเพิ่มข้อมูลเพิ่มเติมเกี่ยวกับการเปลี่ยนแปลงข้อมูลในตาราง โดยจะเป็นการเพิ่ม key เข้าไปซึ่งจะช่วยให้ข้อมูลที่ได้จาก redo log สามารถนำไปใช้งานต่อได้ง่ายขึ้น</p><p>*การเปิดใช้งาน Archive logs และ Redo logs จะทำผ่าน SQL*Plus</p><h3>Step 1. Archive logs</h3><p>ตรวจสอบ LOG_MODE โดยใชเคำสั่ง</p><pre>SELECT LOG_MODE FROM V$DATABASE</pre><p>หากไม่มีการ setup ไว้ LOG_MODE จะมีค่าเป็น NOARCHIVELOG</p><p>ทีนี้จะเริ่มทำการกำหนด parameter สำหรับ archive logs โดยใช้คำสั่ง</p><pre>ALTER SYSTEM SET db_recovery_file_dest_size = 10G;<br>ALTER SYSTEM SET db_recovery_file_dest = &#39;/opt/oracle/oradata/ORCLCDB&#39; scope=spfile;</pre><p><strong>db_recovery_file_dest_size</strong> -&gt; จะเป็นการกำหนดขนาดของความจุที่จะใช้เก็บตัว archive logs</p><p><strong>db_recovery_file_dest</strong> -&gt; จะเป็นตัวกำหนด path directory สำหรับเก็บตัว archive logs</p><p>หลังจากกำหนด parameter แล้วเราจะทำการ restart database โดยใช้คำสั่ง</p><pre>SHUTDOWN IMMEDIATE<br>STARTUP MOUNT</pre><p>หลังจาก start up เรียบร้อยจะทำการเปิดใช้งานตัว archive logs โดยใช้คำสั่ง</p><pre>ALTER DATABASE ARCHIVELOG;<br>ALTER DATABASE OPEN;<br>ARCHIVE LOG LIST;</pre><h3>Step2. Redo logs</h3><p>หลังจากทำการเปิดการใช้งาน archive log แล้วจะทำการตั้งค่าการใช้งาน redo logs โดยใช้คำสั่ง</p><pre>SELECT GROUP#, BYTES/1024/1024 SIZE_MB, STATUS FROM V$LOG ORDER BY 1;</pre><p>โดยจะมีการส่งค่า log group กลับมาซึ่งจะมีการระบุขนาดและ status ของแต่ละ group ไว้และใช้คำสั่งต่อไปนี้เพื่อหาชื่อไฟล์ และที่อยู่ของไฟล์ log ว่าถูกเก็บไว้ใน directory ไหนในเครื่อง</p><pre>SELECT GROUP#, MEMBER FROM V$LOGFILE ORDER BY 1, 2;</pre><p>หลังจากนั้นเราจะทำการปรับขนาดของไฟล์ log จากเดิมที่มี default เป็น 200mb ให้เป็น 400mb โดยใช้คำสั่ง</p><pre>ALTER DATABASE CLEAR LOGFILE GROUP 1;<br>ALTER DATABASE DROP LOGFILE GROUP 1;<br>ALTER DATABASE ADD LOGFILE GROUP 1 (&#39;/opt/oracle/oradata/ORCLCDB/redo01.log&#39;) size 400M REUSE;<br>ALTER SYSTEM SWITCH LOGFILE;</pre><p>หลังจากปรับเสร็จแล้วทำการตรวจสอบโดยใช้คำสั่ง</p><pre>SELECT GROUP#, BYTES/1024/1024 SIZE_MB, STATUS FROM V$LOG ORDER BY 1;</pre><h3>Step3. Supplemental Logging</h3><p>ปกติ Supplemental Log จะไม่ได้ถูกเปิดใช้งานดังนั้น ในการใช้งานร่วมกับ Debezium ต้องเปิดใช้งาน Supplemental Logging ก่อนจึงจะสามรถใช้งานได้โดยใช้คำสั่ง</p><pre>ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fce9146c9669" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก]การติดตั้ง oracle database บน centos 7]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-oracle-database-%E0%B8%9A%E0%B8%99-centos-7-e49b648fe68?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/e49b648fe68</guid>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Mon, 27 Mar 2023 07:10:49 GMT</pubDate>
            <atom:updated>2023-03-27T10:36:06.335Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Step 1. Preinstall</strong></h3><p>เตรียม os user สำหรับลง database โดยในที่นี้จะใช้เป็น user oracle</p><p>เตรียมพร้อมตัว install โดยในขั้นตอนแรกๆแนะนำให้ใช้งาน root user โดยใช้คำสั่ง</p><pre>sudo su</pre><pre>yum -y update</pre><p>เตรียม file preinstall และ install</p><p>Download ตัว rpm โดยใช้ curl</p><pre>curl -o oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm</pre><p>ทำการ loacal install</p><pre>yum -y localinstall oracle-database-preinstall-19c-1.0-1.el7.x86_64.rpm</pre><h3>Step 2. Install base rpm</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i9vJ3y6znv1MGasLaJPpMA.png" /></figure><p>Download file install ที่เป็น rpm จาก <a href="https://www.oracle.com/database/technologies/oracle-database-software-downloads.html">https://www.oracle.com/database/technologies/oracle-database-software-downloads.html</a> <br>โดย ใช้ rpm ที่เป็น <strong>19.3 — Enterprise Edition </strong>Linux x86–64</p><p>ทำการ install โดยใช้</p><pre>yum -y localinstall oracle-database-ee-19c-1.0-1.x86_64.rpm</pre><h3>Step 3. Creating and Configuring</h3><p>หลังจาก install เรียบร้อยจะทำการเริ่ม config database โดยใช้คำสั่ง</p><pre>/etc/init.d/oracledb_ORCLCDB-19c configure</pre><h3>Step 4. Firewall</h3><p>ทำการเพิ่ม port 1521 เข้าไป</p><pre>firewall-cmd --add-port=1521/tcp --permanent</pre><p>จากนั้นทำการ reload</p><pre>firewall-cmd --reload</pre><p>ตรวจสอบโดยใช้คำสั่ง</p><pre>firewall-cmd --list-ports 1521/tcp</pre><h3>Step5.Edit Environment variables</h3><p>ในขั้นตอนนี้จะเป็นการตั้งค่า ORACLE_HOME , PATH ,ORACLE_SID , LANG โดยจะต้องทำการสลับ user โดยใช้คำสั่ง</p><pre>su oracle</pre><p>ทำการแก้ไขไฟล์ .bashrc</p><pre>nano ~/.bashrc</pre><p>เพิ่มข้อความต่อไปนี้เข้าไปในไฟล์</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/723/1*OCslx3pMmwBNO9qiidRtDg.png" /></figure><pre>export LANG=en_US.UTF-8<br>export ORACLE_HOME=/opt/oracle/product/19c/dbhome_1 <br>export PATH=$PATH:/opt/oracle/product/19c/dbhome_1/bin <br>export ORACLE_SID=ORCLCDB</pre><p>หลังจาก save แล้วทำการ refresh ด้วยคำสั่ง</p><pre>source ~/.bashrc</pre><h3>Step 6. Listener</h3><p>จากนั้นเราจะทำการตรวจสอบตัว listener ว่าทำงานปกติหรือไม่ด้วยคำสั่ง</p><pre>lsnrctl status</pre><p>หาก listener ยังไม่ถูกเปิดจะมีข้อความหน้าตาแบบนี้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/832/1*78z-cpgexOiKuEBv1jfLJQ.png" /></figure><p>ให้เราทำการ start โดยใช้คำสั่ง</p><pre>lsnrctl start</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eElTvcynn6t-6Thlw4sLGw.png" /></figure><h3>Step 7. ทดลองใช้ sqlplus</h3><p>ทำลองเข้าใช้งาน database ด้วยคำสั่ง</p><pre>sqlplus / as sysdba</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/1*iC0b3oLbzyJwW05pdaq7PQ.png" /><figcaption>หากสำเร็จจะเจอกับหน้าตาแบบนี้</figcaption></figure><p>ทำการกำหนด password ให้กับ user system ด้วยคำสั่ง</p><pre>alter user system identified by &lt;กำหนด password&gt;;</pre><p>หลังจากนั่นสามาถทำการทดสอบ remote login ด้วย dbeaver ได้</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/404/1*eewvkn37wUl7NrV9ixr7zQ.png" /></figure><h3>Step 8. Create user/schema</h3><p>ในส่วนนี้จะเป็นการสร้าง user สำหรับ remote เข้ามาใสช้งานกรณีที่ไม่อยากใช้ system โดยใน sql plus จะใช้คำสั่ง</p><pre>CREATE USER &lt;username&gt; IDENTIFIED BY &lt;password&gt;;</pre><p>เมื่อ success แล้วจะ grant ให้ user สามารถเข้าถึง Oracle Database ได้จาก remote ด้วยคำสั่ง</p><pre>GRANT CREATE SESSION TO &lt;username&gt;;</pre><p>ถ้าต้องการให้ user สามารถสร้าง table space และ objects อื่น ๆ ใน Oracle Database ได้ ให้ใช้คำสั่ง</p><pre>GRANT ALL PRIVILEGES TO &lt;username&gt;;</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e49b648fe68" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก] เชื่อมต่อ Debezium กับ Kafka]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-%E0%B9%80%E0%B8%8A%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%A1%E0%B8%95%E0%B9%88%E0%B8%AD-debezium-%E0%B8%81%E0%B8%B1%E0%B8%9A-kafka-f06b27e9e5a6?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/f06b27e9e5a6</guid>
            <category><![CDATA[kafka-connect]]></category>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Fri, 10 Mar 2023 13:58:17 GMT</pubDate>
            <atom:updated>2023-03-14T12:33:42.093Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/765/1*x_pajIyFATweDwZKxdhkow.png" /><figcaption><a href="https://debezium.io/blog/2017/09/25/streaming-to-another-database/">https://debezium.io/blog/2017/09/25/streaming-to-another-database/</a></figcaption></figure><p>การเชื่อมต่อ kafka กับ databaseภายนอกเราจะใช้ตัว connector ในการเชื่อมโดยตัว connector จะมีทั้งหมด3แบบได้แก่ connect-standalone , connect-mirror และ connect-distributed ใช้สำหรับการนำเข้า/ส่งออกข้อมูลจาก Kafka ไปยังระบบภายนอก</p><ul><li>connect-standalone : เป็นโหมดการทำงานของ Kafka Connect ที่ทำงานเป็นแบบ standalone หรือเดี่ยว ไม่มีการใช้ worker หลายๆตัวเหมือนกับ connect-distributed โดยการทำงานของมันจะเป็นการตั้งค่า worker เพียงตัวเดียว และจะต้องทำการรัน Kafka Connect หลายๆ เซสชั่นเพื่อรองรับการทำงานแบบ parallel</li><li>connect-mirror : ใช้สำหรับทำ Mirror ข้อมูลจาก Kafka Cluster หรือ Topic ไปยัง Kafka Cluster หรือ Topic อื่นๆ โดย Mirror คือการทำซ้ำ หรือ copy ข้อมูลจาก Kafka Cluster หรือ Topic ไปยังอีก Kafka Cluster หรือ Topic ที่ต่างกัน</li><li>connect-distributed : เป็นโหมดการทำงานของ Kafka Connect ที่ใช้ worker หลายๆตัว โดยการทำงานของมันจะเป็นการสร้าง worker หลายๆตัว ทำงานแบบ distributed แต่ละตัวแบ่งงานกันทำการเชื่อมต่อและคอนฟิกกับ Kafka Broker เพื่อการนำเข้า/ส่งออกข้อมูล ทำให้สามารถ scale ระบบได้เพื่อรองรับการทำงานแบบ parallel หรือยืดหยุ่นกับการปรับปรุงประสิทธิภาพของระบบได้ง่ายขึ้น</li></ul><p>ในการใช้งานครั้งนี้เราจะใช้ตัว connect-standalone ในการทดสอบการเชื่อมต่อไปยังต้นทาง mysql database(เก็บข้อมูลปกติ) และปลายทางเป็น mysql database(สำหรับเก็บข้อมูลจาก topic จาก kafka) โดยเราจะfocus ไปที่การตั้งค่าในไฟล์ config ที่ใช้สำหรับเชื่อมต่อโดนเริ่มจากการ config สำหรับ mysql(เก็บข้อมูลปกติ)</p><h3>Step 1. ติดตั้ง Debezium</h3><p>โดยเราจะทำการ download file debezium มาที่เครื่องโดยใช้คำสั่ง</p><pre>wget https://repo1.maven.org/maven2/io/debezium/debezium-connector-mysql/1.9.7.Final/debezium-connector-mysql-1.9.7.Final-plugin.tar.gz</pre><pre>tar -xzf debezium-connector-mysql-1.9.7.Final-plugin.tar.gz</pre><p>ทำการย้าย folder ที่ได้มาด้วยคำสั่ง</p><pre>mv debezium-connector-mysql /home/&lt;ที่อยู่ directory ที่ติดตั้ง kafka&gt;/kafka</pre><h3>Step 2. ติดตั้ง Confluent jdbc connector</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c0t2g3TdrKnz7ORKCPaGxQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IQ5FOqTmP_-Fgu-Ldtsn6Q.png" /></figure><p>ทำการ download <a href="https://www.confluent.io/hub/confluentinc/kafka-connect-jdbc">https://www.confluent.io/hub/confluentinc/kafka-connect-jdbc</a> ไว้ที่เครื่องและทำการแตกไฟล์ จากนั้นทำการย้ายไฟล์ไปไว้ใน directory เดียวกันกับ Debezium ด้วยคำสั่ง</p><pre>mv confluentinc-kafka-connect-jdbc-10.6.3 /home/&lt;ที่อยู่ directory ที่ติดตั้ง kafka&gt;/kafka</pre><h3>Step 3. ติดตั้ง connector ของ mysql</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4a3crt4JEbNdnIW90_s5HQ.png" /></figure><p>ทำการ download ไฟล์จาก <a href="https://dev.mysql.com/downloads/connector/j/">https://dev.mysql.com/downloads/connector/j/</a> มาไว้ที่เครื่องจากนั้นจะทำการย้ายไฟล์ .jar โดยใช้คำสั่ง</p><pre>mv mysql-connector-j_8.0.32-1ubuntu22.04_all.deb /home/&lt;ที่อยู่ directory ที่ติดตั้ง kafka&gt;/kafka</pre><h3>Step 4. ตั้งค่า Connector สำหรับเชื่อมต่อ mysql(เก็บข้อมูลปกติ)</h3><p>เข้าไปที่ directory /config และทำการสร้างไฟล์ properties โดยใช้คำสั่ง</p><pre>nano mysql-connector.properties</pre><p>โดยภายในไฟล์ <em>mysql-connector.properties</em> จะประกอบไปด้วย</p><pre>name=sql-connect<br>connector.class=io.debezium.connector.mysql.MySqlConnector<br>tasks.max=1<br>database.hostname=&lt;ip เครื่อง mysql ที่เราต้องการ capture change&gt;<br>database.port=3306<br>database.user=&lt;username ของเครื่อง mysql&gt;<br>database.password=&lt;password ของเครื่อง mysql&gt;<br><br>database.server.id=&lt;ID ของ MySQL server สามารถกำหนดเองได้&gt;<br>database.server.name=&lt;ชื่อของ MySQL server สามารถกำหนดเองได้&gt;<br><br>database.history.kafka.bootstrap.servers=&lt;ip เครื่อง kafka ทำการบันทึกการกระทำต่างๆที่เกิดขึ้นใน database&gt;<br><br>database.history.kafka.topic=&lt;ชื่อ topic ของ Kafka ที่จะใช้เพื่อเก็บข้อมูลจาก database&gt;<br>database.whitelist=&lt;ชื่อของ database ที่ต้องการให้ Connector เชื่อมต่อ *สามารถระบุได้มากกว่า 1 schema&gt;<br>database.include.list=&lt;ชื่อของ database ที่ต้องการให้ Connector เชื่อมต่อ *สามารถระบุได้มากกว่า 1 schema&gt;<br><br>transforms=route<br>transforms.route.type=org.apache.kafka.connect.transforms.RegexRouter<br>transforms.route.regex=([^.]+)\\.([^.]+)\\.([^.]+)<br>transforms.route.replacement=$3<br><br>ransforms = unwrap,dropTopicPrefix<br>transforms.unwrap.type = io.debezium.transforms.ExtractNewRecordState<br>transforms.unwrap.drop.tombstones = false<br>delete.handling‹.mode = none<br>transforms.dropTopicPrefix.type = org.apache.kafka.connect.transforms.RegexRouter<br>transforms.dropTopicPrefix.regex = &lt;server name&gt;.&lt;table name&gt;.(.*)<br>transforms.dropTopicPrefix.replacement = $1<br>include.schema.changes : true</pre><h3>Step 5. Connector สำหรับเชื่อมต่อ mysql(ที่ใช้เก็บข้อมูลจาก kafka)</h3><pre>nano jdbc-connector.properties</pre><p>โดยภายในไฟล์ <em>jdbc-connector.properties</em> จะประกอบไปด้วย</p><pre>name=jdbc-connector<br>connector.class=io.confluent.connect.jdbc.JdbcSinkConnector<br>tasks.max=1<br>topics=&lt;ชื่อ topic&gt;<br>connection.url=jdbc:mysql://&lt;ip เครื่อง mysql พร้อม port&gt;/&lt;ชื่อ schema ที่จะใช้เก็บข้อมูลจาก kafka&gt;<br>connection.user=&lt;username ของเครื่อง mysql&gt;<br>connection.password=&lt;password ของเครื่อง mysql&gt;<br>transforms=unwrap<br>transforms.unwrap.type=io.debezium.transforms.ExtractNewRecordState<br>transforms.unwrap.drop.tombstones=false<br>auto.create=true<br>delete.enabled=true<br>insert.mode=upsert<br>pk.mode=record_key<br>pk.fields=&lt;กำหนด fields ที่จะใช้เป็น primary key&gt;</pre><blockquote>สำหรับ pk.mode เป็นการกำหนดวิธีการจัดการกับ Primary Key ของตารางในฐานข้อมูล โดยมีค่าที่สามารถกำหนดได้ดังนี้<br>none - ไม่ใช้ Primary Key ในการจัดการข้อมูล<br>record_key - ใช้ค่า key ของ Kafka record เป็น Primary Key ในการจัดการข้อมูล<br>record_value - ใช้ค่า value ของ Kafka record เป็น Primary Key ในการจัดการข้อมูล<br>record_headers - ใช้ค่า headers ของ Kafka record เป็น Primary Key ในการจัดการข้อมูล<br>custom - ใช้ฟิลด์ที่กำหนดเองเป็น Primary Key ในการจัดการข้อมูล<br>โดยค่า default คือ none</blockquote><blockquote>ส่วนค่า insert.mode เป็นการกำหนดวิธีการจัดการข้อมูลที่ถูกส่งมาจาก Kafka topic ไปยังฐานข้อมูล โดยมีค่าที่สามารถกำหนดได้ดังนี้<br>insert - จะทำการ insert ข้อมูลใหม่เมื่อไม่พบ Primary Key หรือเมื่อพบ Primary Key แต่ไม่มีข้อมูลในตาราง<br>upsert - จะทำการ update ข้อมูลเมื่อพบ Primary Key และมีข้อมูลอยู่ในตาราง หรือทำการ insert ข้อมูลใหม่เมื่อไม่พบ Primary Key หรือไม่มีข้อมูลในตาราง<br>update - จะทำการ update ข้อมูลเมื่อพบ Primary Key และมีข้อมูลอยู่ในตาราง แต่ไม่ทำการ insert ข้อมูลใหม่เมื่อไม่พบ Primary Key หรือไม่มีข้อมูลในตาราง<br>delete - จะทำการ delete ข้อมูลเมื่อพบ Primary Key<br>โดยค่า default คือ insert หากไม่ระบุ insert.mode ในการกำหนดค่าใหม่.</blockquote><h3>Step 6. ตั้งค่า plugin</h3><p>ทำการแก้ไขไฟล์ connect-standalone.properties ด้วยคำสั่ง</p><pre>nano connect-standalone.properties</pre><p>ทำการเพิ่ม path directory ของ plugin ในบรรทัด</p><pre>plugin.path=/home/kafka/Downloads , /usr/share, /usr/bin/java , /home/&lt;kafka_install&gt;/kafka_2.13-3.4.0</pre><h3>Step 7. Start connector</h3><p>ให้เราเข้าไปที่ path /bin และใช้คำสั่งต่อไปนี้เพื่อเริ่มการทำงานของ connector</p><pre>./connect-standalone.sh ../config/connect-standalone.properties ../config/mysql-connector.properties ../config/jdbc-connector.properties</pre><p>ตรวจสอบ console ว่าพบ error หรือไม่หากไม่พบแปลว่าตอนนี้เราสามารถเชื่อมต่อเข้ากับ mysql ทั้งสองฝั่งได้เรียบร้อยแล้ว</p><p>*กรณีที่เราต้องการต่อ jdbc เข้ากับตัว PostgreSQL สามารถใช้ค่า config คล้ายๆกับตอนเชื่อต่อไปยัง mysql ได้เลย</p><pre>name=&lt;ชื่อ conector&gt;<br>connector.class=io.confluent.connect.jdbc.JdbcSinkConnector<br>tasks.max=1<br>topics=&lt;ชื่อ topic&gt;<br>connection.url=jdbc:postgresql://&lt;ip เครื่อง postgre&gt;/&lt;database name&gt;<br>connection.user=&lt;username&gt;<br>connection.password=&lt;password&gt;<br>transforms=unwrap<br>transforms.unwrap.type=io.debezium.transforms.ExtractNewRecordState<br>transforms.unwrap.drop.tombstones=false<br>auto.create=true<br>delete.enabled=true<br>insert.mode=upsert<br>pk.mode=record_key<br>pk.fields=&lt;กำหนด primary key&gt;</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f06b27e9e5a6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[[บันทึก] ติดตั้ง kafka ใน ubuntu]]></title>
            <link>https://medium.com/@jackchawanwit/%E0%B8%9A%E0%B8%B1%E0%B8%99%E0%B8%97%E0%B8%B6%E0%B8%81-%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-kafka-%E0%B9%83%E0%B8%99-ubuntu-b6eb2d90c5f6?source=rss-7f60902f5fdd------2</link>
            <guid isPermaLink="false">https://medium.com/p/b6eb2d90c5f6</guid>
            <category><![CDATA[kafka]]></category>
            <dc:creator><![CDATA[Jack Tanaraksak]]></dc:creator>
            <pubDate>Tue, 07 Mar 2023 14:09:28 GMT</pubDate>
            <atom:updated>2023-03-07T14:09:28.203Z</atom:updated>
            <content:encoded><![CDATA[<p>สิ่งที่ต้องเตรียมในการลง kafka</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZcLt6rX8_GU4JxpMfyY7bA.png" /></figure><ul><li>เครื่อง Ubuntu (ณ ตอนที่เขียนใช้ version 22.04)</li><li>ในการลงจะเป็นการติดตั้งผ่านตัว terminal ภายในเครื่อง แนะนำให้ใช้งานด้วย root user</li></ul><h3><strong>Step 1. Setup machine</strong></h3><p>ทำการเช็คความพร้อมของตัวเครื่องที่เราจะลง kafka เริ่มจากการตรวจสอบ version ของ java ในตัวเครื่องว่าได้มีการลง java ไปแล้วหรือยังด้วยคำสั่ง</p><pre>java -version</pre><p>จากนั้นทำการ update ตัว apt-get ด้วยคำสั่ง</p><pre>sudo apt-get update</pre><p>หลังจากที่ได้ทำการ update เรียบร้อยแล้วและภายในเครื่องยังไม่ได้มีการติดตั้ง java ไว้เราจะใช้คำสั่ง</p><pre>sudo apt install default-jdk</pre><p>เพื่อทำการติดตั้ง java ลงไปที่เครื่อง ubuntu ของเรา</p><h3><strong>Step 2. Download &amp; Setup</strong></h3><p>ทำการ download kafka จาก <a href="https://kafka.apache.org/downloads">https://kafka.apache.org/downloads</a> และทำการเลือก download ไฟล์นามสกุล kafka_2.12–3.x.0.tgz (สามารถใช้ web browser ในเครื่อง download ได้เลย)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vIrl0JmPjk05ycR1p1nxTQ.png" /></figure><p>โดยหลังจาก download เสร็จให้เราเข้าไปที่ Dowload directory ที่เก็บไฟล์ไว้ผ่านทาง terminal และทำการแตกไฟล์โดยใช้คำสั่ง</p><pre>tar xzf kafka_2.12-3.4.0.tgz</pre><p>จากนั้นทำการย้าย folder ของ kafka ไปยัง directory อื่นๆด้วยคำสั่ง</p><pre>mv kafka_2.12-3.4.0 /home/&lt;ตำแหน่ง directory ที่เราต้องการนำ folder ไปวาง&gt;</pre><h3>Step 3. Config</h3><p>ให้เราเข้าไปยัง folder ของ kafka ที่เราได้ย้ายไปและเข้าไปใน directory config</p><pre>cd &lt;directory ที่เราย้ายไฟล์มา&gt;/kafka_2.12-3.4.0/config</pre><p>จากนั้นเราจะทำการตั้งค่าตัว server.properties โดยใช้คำสั่ง</p><pre>nano server.properties</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/608/1*OTmsJXRYz1fCP-_XYLh6lg.png" /></figure><p>ทำการลบ comment บรรทัดที่มีค่า “listeners=PLAINTEXT://localhost:9092” และทำการเพิ่ม “advertised.host.name=localhost” เข้าไปอีก 1 บรรทัด แล้วกด ctrl+x เพื่อออกจากหน้าจอแก้ไข</p><h3>Step 4. Start</h3><p>หลังจากที่ทำการ config เรียบร้อยแล้วให้เราย้ายไปที่ directory /bin</p><pre>cd &lt;kafka location&gt;/kafka_2.12-3.4.0/bin</pre><p>และจะเริ่มทำการ start ตัว zookeeper ด้วยคำสั่ง</p><pre>.zookeeper-server-start.sh config/zookeeper.properties</pre><p>หลังจาก start zookeeper เรียบร้อยไม่มี error เราทำการ start ตัว kafka โดยจะทำการเปิด terminal เพิ่มอีก 1 หน้าต่างแล้วทำการเข้ามายัง directory /bin และใช้คำสั่ง start kafka</p><pre>.kafka-server-start.sh config/server.properties</pre><p>ทำการ check start log ว่ามี error อะไรหรือไม่</p><h3>Step 5. Test</h3><p>หลังจากที่เรา start kafka ได้สำเร็จแล้วจะทำการทดลองใช้งานกันดูโดยเปิด terminal หน้าต่างใหม่ขึ้นมา แล้วทำการเข้าไปยัง directory /bin</p><p>คำสั่งสำหรับ check topic ในเครื่อง</p><pre>./kafka-topics.sh --list --bootstrap-server localhost:9092</pre><p>คำสั่งสำหรับสร้าง topic</p><pre>.kafka-topics.sh --create --topic &lt;ชื่อ topic&gt; --bootstrap-server localhost:9092</pre><p>คำสั่งสำหรับส่ง message เข้าไปยัง topic ผ่านตัว kafka-console</p><pre>./kafka-console-producer.sh --topic &lt;ชื่อ topic&gt; --bootstrap-server localhost:9092</pre><p>คำสั่งสำหรับแสดง message ที่อยู่ใน topic</p><pre>./kafka-console-consumer.sh --topic &lt;ชื่อ topic&gt; --bootstrap-server localhost:9092 --from-beginning</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b6eb2d90c5f6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>