<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>under_the_sky.log</title>
        <link>https://velog.io/</link>
        <description>내 머릿 속에 뭐가 들어있는지 알 수 있는 공간</description>
        <lastBuildDate>Wed, 05 Jul 2023 05:59:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>under_the_sky.log</title>
            <url>https://velog.velcdn.com/images/under_the_sky/profile/5fced3ed-d54a-410c-bafc-a85b1c047a73/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. under_the_sky.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/under_the_sky" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[하둡에코시스템]]></title>
            <link>https://velog.io/@under_the_sky/%ED%95%98%EB%91%A1%EC%97%90%EC%BD%94%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@under_the_sky/%ED%95%98%EB%91%A1%EC%97%90%EC%BD%94%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Wed, 05 Jul 2023 05:59:04 GMT</pubDate>
            <description><![CDATA[<p>하둡 에코시스템
우리는 여러 프레임워크를 알아보았다. 하둡에서 <strong>데이터를 분석 유지 저장 관리 할 때 필요한 모든 것들을 에코시스템</strong>이라 한다. 즉, 하둡은 <strong>효율적인 데이터 처리와 분석을 위해</strong> 맵리듀스, 분산형 파일시스템(HDFS) 말고도 많은 구성요소로 포함된다. 구성요소들에 대해 알아보도록 하자.</p>
<blockquote>
<p>*<em>하둡 코어 프로젝트 *</em>: HDFS(분산데이터 저장), MapReduce(분산처리)</p>
</blockquote>
<blockquote>
<p><strong>하둡 서브 프로젝트</strong> : 하둡 코어 프로젝트를 제외한 나머지 프로젝트로 데이터 마이닝, 수집, 분석 등을 수행한다.</p>
</blockquote>
<p><strong>하둡 서브 프로젝트 (분산데이터를 다루기 위해 만들어진 추가 project)</strong>
지금부터는 기존의 데이터가 아닌 분산 데이터이기 때문에 새롭게 생긴 용어들이다. 사실상 기존의 데이터를 다루는 데 사용되어지는 개념이지만, 분산되어 저장된 데이터를 처리하는 방식에 대한 이름을 붙인 것이라고 할 수 있다.</p>
<blockquote>
<p>하둡 에코시스템
<img src="https://velog.velcdn.com/images/under_the_sky/post/26601a26-11ca-4334-a352-eaf1a0f102e0/image.png" alt=""></p>
</blockquote>
<blockquote>
<p>주요 기술별 역할
<img src="https://velog.velcdn.com/images/under_the_sky/post/4e95fafc-7d69-4576-b71f-21c0775d68a2/image.png" alt=""></p>
</blockquote>
<p><strong>작업 흐름도</strong>
HDFS(하둡 저장 시스템) =&gt; MapReduce(데이터를 key value로 변경) =&gt; Hbase(변경된 데이터를 데이터베이스로 저장) =&gt; Pig, Hive, Mahout, Oozie(데이터를 분석해주는 툴)</p>
<hr>
<h3 id="0-하둡-사용자-인터페이스hue-zeppelin">0. 하둡 사용자 인터페이스(Hue, Zeppelin)</h3>
<p>하둡 휴(Hue, Hadoop User Experience)는 <strong>하둡과 하둡 에코시스템의 지원을 위한 웹 인터페이스를 제공하는 오픈 소스</strong> 이다. <strong>Hive 쿼리를 실행하는 인터페이스를 제공하고, 시각화를 위한 도구를 제공</strong>한다. 잡의 스케줄링을 위한 인터페이스와 잡, HDFS, 등 하둡을 모니터링하기 위한 인터페이스도 제공한다.</p>
<p>Zeppelin은 한국의 NFLab이라는 회사에서 개발하여 Apache top level 프로젝트로 최근 승인 받은 오픈소스 솔루션으로, <strong>Notebook 이라고 하는 웹 기반 Workspace</strong>에 <strong>Spark, Tajo, Hive, ElasticSearch 등 다양한 솔루션의 API, Query 등을 실행하고 결과를 웹에 나타내는 솔루션</strong>입니다.</p>
<ul>
<li>Flamingo framework</li>
</ul>
<h3 id="1-hbase">1. Hbase</h3>
<p><strong>하둡에서 사용하는 데이터베이스</strong>는 <strong>관계형 데이터베이스</strong>가 아닌 <strong>NoSQL(비정형화된 데이터베이스)</strong> 이다. Hbase는 자바 언어로 만들어졌으며, <strong>HDFS를 이용하여 분산된 컴퓨터에 데이터를 저장</strong>한다. 그리고 Hbase는 압축 기능과 자주 사용되는 데이터를 미리 메모리에 캐싱하는 인-메모리(In-Memory)기술을 사용하여 데이터 검색 속도를 높인다.</p>
<p>HDFS와 Hbase가 헷갈릴 수 있다. <strong>HDFS가 원초적인 데이터를 분산저장 하는 곳</strong>이라고 생각하면되고, <strong>Hbase는 그 원초적 데이터를 가져와서 key, value 형태와 같이 가공을 해서 쉽게 가져다 쓸 수 있게 만든 데이터베이스</strong>라고 생각하면 된다.</p>
<p><strong>NoSQL(Not Only SQL)</strong>은 <strong>대용량 데이터를 처리하기 위해서 탄생된 데이터베이스</strong>이다. 대용량 데이터를 저장하고 처리하기 위해서는 지리적으로 분산되어 있는 노드들에 대한 안정적인 관리가 필요하며, 속도보다는 데이터를 손실하지 않고 저장하는 방법과 더 많은 데이터를 처리하기 위해서 노드들을 쉽게 확장할 수 있는 방법에 중점을 두고 설계가 되었다고 보면 된다.</p>
<p>NoSQL의 큰 종류에 대해 알아보자. <strong>&#39;Key-Value store&#39; 제품군</strong>으로는 멤캐시드(Mem-Cached)와 레디스(Redis, Remote Dictionary Server)등이 있으며, 키-밸류 형태로 이루어진 비교적 단순한 데이터 타입을 데이터베이스에 저장한다. <strong>&#39;Graph Database&#39;</strong> 제품에는 네오포제이(Neo4j)가 있으며, 그래프 모델에서 필요한 정점(Vertex)와 간선(Edge) 그리고 속성(Property)등과 같은 정보를 데이터베이스에 저장하고, <strong>&#39;Document Store&#39; 제품군</strong>에는 카우치DB와 몽고DB가 있으며, 문서 형태의 정보를 JSON 형식으로 데이터베이스에 저장한다. 마지막으로 <strong>&#39;Wide Colum Store&#39; 제품군</strong>에는 H베이스(HBase)와 카산드라(Cassandra)가 있으며, 컬럼안에 여러 정보들을 JSON 형태로 저장할 수 있다.</p>
<p>하둡 진영에서는 관계형 데이터베이스에 호감을 가지고 있는 분석가와 사용자들의 마음을 돌리기 위해서, <strong>빠른 속도와 손 쉬운 사용 그리고 관계형 데이터베이스에서 사용하던 도구들을 이용할 수 있는 시스템</strong>을 만들기 위해서 노력하고 있다. 이러한 데이터베이스 제품들을 &#39;NewSQL&#39;이라고 부르고 있으며, 여기에는 그루터(Gruter)의 타조(Tajo), 구글의 드레멜(Dremel), 호튼웍스의 스팅어(Stinger), 클라우데라의 임팔라(Impala)등이 있다. 관련 내용은 아래의 Hive에서 다시 나오니 참고하자.</p>
<h3 id="2-주키퍼zookeeper">2. 주키퍼(Zookeeper)</h3>
<p>Zookeeper(사육사)는 이름에서 그 역할을 쉽게 짐작할 수 있다. <strong>분산 시스템 간의 정보 공유 및 상태 체크, 동기화를 처리하는 프레임워크</strong>로 이러한 시스템을 <strong>코디네이션 서비스 시스템</strong>이라고 한다. Zookeeper를 많이 사용하는 이유는 <strong>기능에 비해 시스템이 단순</strong>하기 때문이다. 분산 큐, 분산 락, 피어 그룹 대표 산출 등 다양한 기능을 가진다. 쉽게 설명하면, 리소스와 하둡의 구성요소 간의 불일치 문제를 중간에서 해결하는 역할이다</p>
<h3 id="3-pig와-hive-project">3. Pig와 Hive Project</h3>
<p> 맵리듀스을 구현을 하려면 여러 언어들을 사용해야한다. 기본적으로 하둡은 자바로 개발되어 있기 때문에, 가장 많이 활용되는 언어는 자바이다.(다른 언어도 지원을 한다.) 따라서 초창기는 MapReduce를 자바를 통해서 직접 코딩을 했다. 그러나 자바코드는 굉장히 길기 때문에 <strong>자동으로 자바가 작동할수 있도록 스크립트 언어</strong>를 만들었는데, 그것이 Pig와 Hive이다.</p>
<blockquote>
<p>Pig : [Yahoo] 많은 사람들이 사용할 수 있도록 MapReduce 프로그램을 만들어 주는 고수준 언어를 만들겠다는 목적으로 만들어짐
HIVE : [Facebook] SQL(유사) 구문에서 MapReduce를 자동생성하겠다는 목적으로 만들어짐</p>
</blockquote>
<p>정리하면, Pig와 HIVE의 탄생으로 어려운 자바을 통해 MapReduce를 할 필요없어진 것이다.</p>
<h4 id="31-pig-project">3.1 Pig Project</h4>
<p>맵리듀스 어플리케이션으로 개발해서 처리할 수도 있지만, 맵리듀스를 사용하지 않고 <strong>Pig를 사용해서도 분산파일 시스템에 저장된 데이터를 처리</strong>할 수 있게 만든 스크립트 언어이다. Pig는 Yahoo에서 개발되어 졌으며, Pig Latin language는 SQL과 유사한언어를 기본으로한 쿼리이다. pig는 명령 실행 작업을 수행한 후에 백그라운드에서 MapReduce의 모든 활동을 처리한다. 처리 후엔 결과물를 HDFS에 저장한다.</p>
<h4 id="32-hive-project">3.2 Hive Project</h4>
<p>하둡은 하이브(Hive)가 없었던 시절인 하둡 v1에서는 맵-리듀스(Map-Reduce) 언어를 사용하여 하둡 분산 파일 시스템(HDFS)에 저장된 정보들을 조회(Query) 했다. 그러나 프로그램을 모르는 일반 사용자들이 맵-리듀스 언어를 사용하여 조회(Query)하는 일이 어려울 수 밖에 없었다. 이러한 문제점을 해결하기 위한 하이브는 <strong>하이브큐엘(HiveQL)이라는SQL과 거의 유사한 언어를 사용하여 일반 사용자들이 쉽게 데이터를 조회(Query)할 수 있도록 지원</strong>한다. </p>
<p>데이터를 다루는데는 <strong>관계형데이터베이스인 SQL이 일반적으로 가장 많이 사용</strong>된다. 따라서 <strong>분산파일로 저장된 데이터</strong>를 <strong>SQL로 다루기 위해 탄생한 것이 Hive</strong>이다. 최근에는 <strong>Hive를 활용하여 분산파일을 핸들링하는 것이 가장 일반적인 방법</strong>이다. 그러나 정형데이터의 경우만 SQL로 처리하는 것이 가능하고 반정형 데이터나 <strong>비정형 데이터는 SQL로 처리하기가 쉽지가 않다</strong>. 이런 경우는 맵리듀스로 다시 프로그래밍을 해야할 필요가 있다. 정리하면 Hive는 SQL로 분산데이터 처리를 하기 위한 것이다.</p>
<p><strong>SQL 방법론 및 인터페이스의 도움</strong>으로 HIVE는 대용량 데이터 세트를 읽고 쓰기가 가능해진다. 쿼리 언어는 HQL (Hive Query Language)라고 불리며 실시간 처리와 일괄 처리를 모두 허용하므로 확장성이 뛰어나고 <strong>모든 SQL 데이터 유형이 Hive에서 지원</strong>되므로 쿼리 처리가 더 쉬워진다.</p>
<p>하지만 <strong>하이브에도 몇가지 단점</strong>이 있다. <strong>하이브큐엘(HiveQL)을 통해서 조회(Query)를 실행하</strong>면 내부적으로 <strong>맵-리듀스 언어로 변환하는 작업</strong>을 거치기 때문에, <strong>맵-리듀스는 맵과 리듀스간의 셔플링 작업으로 인하여 속도가 느리다는 단점</strong>이 있다. 하이브큐엘(HiveQL)이 일반 사용자들에게 손쉽게 조회(Query)할 수 있는 방법을 제공하고 있지만 <strong>처리 속도가 느리다는 문제점</strong>은 여전히 가지고 있고, 하이브큐엘(HiveQL) 언어는 SQL과 비슷한 언어이지만 <strong>표준 SQL(Ansi SQL)의 규칙을 준수하지 않으며</strong>, 사용자들은 이러한 차이점을 다시 배워야하는 문제점을 가지고 있다.</p>
<p>하이브가 가지고 있는 문제점을 개선하기 위한 하둡 진영은 크게 두 갈래로 나뉘게 된다. <strong>&quot;하이브를 완전히 대체하는 새 기술을 쓸 것인가?&quot;</strong> 아니면 <strong>&quot;하이브를 개선해 속도를 높일 것인가?&quot;</strong> 이다. </p>
<p>하이브를 살려야 한다는 입장을 가장 강력하게 내세운 회사는 <strong>호튼웍스이</strong>다. 호튼웍스는 하이브를 최적화하고 파일 포맷 작업을 통해 하이브 쿼리 속도를 100배 끌어올리겠다는 비젼을 내 놓았다. 이것이 바로 스팅어(Stinger)이다. </p>
<p>하이브를 버리고 새로운 엔진을 찾아야 한다는 진영은 <strong>그루터의 타조와 클라우데라의 임팔라</strong>가 있다. 타조는 하이브를 개선하는데 한계가 명확하기 때문에 대용량  SQL 쿼리 분석에 적합하지 않다는 입장이며, 기획 단계부터 하이브를 대체하는 새로운 엔진을 개발하고 있다. 클라우데라의 임팔라는 좀 특이한 경우인데, 일정 규모 이상의 데이터는 임팔라로 분석이 불가능하다. 임팔라는 메모리 기반 처리 엔진이어서, 일정 용량 이상에서는 디스크 환경의 하이브를 사용해야 한다. 하지만 전체 틀에서는 하이브를 버리는 쪽으로 무게를 두고 있다고 이해하면 된다.</p>
<h3 id="4-mahout마하웃">4. Mahout(마하웃)</h3>
<p>복잡한 머신러닝이나 인공지능 알고리즘을 큰 데이터를 가지고 처리하려면, 별도의 알고리즘이 구현되어 있는 구현체가 필요하다. 즉, <strong>머신러닝 알고리즘을 분산데이터에서 처리할 수 있도록 만드는 아웃풋 구현체</strong>라고 할 수 있다.</p>
<h3 id="5-sqoop">5. Sqoop</h3>
<p><strong>관계형데이터베이스(ex_마리아DB, 오라클, MySQL)와 하둡 간 데이터를 주고받는 것</strong>을 쉽게 할 수 있는 프레임워크이다. 보통 Sqoop은 정형화된 데이터를 수집하는 기술로 많이 쓰인다. 만약, 소셜 네트워크 서비스에서 만들어지는 비정형 데이터의 경우는 클라우데라(Cloudera)의 플룸(Flume)과 아파치(Apache) 척화(Chukwa)등이나, 페이스북에서 사용하는 스크라이브(Scribe)를 비정형데이터 수집 기술로 쓰인다..</p>
<h3 id="6-hcatalog">6. HCatalog</h3>
<p><strong>하둡에 저장된 데이터를 다루는 엔진</strong>이다. 사용자마다 자신이 편한 Hive나 Pig 등 다른 명령어를 사용한다. 이럴 때 기본적인 메타나 스키마를 통일되게 공유하는 경우가 필요하다. 즉, HCatalog는 하나의 카탈로그로 관리를 하겠다는 의미이다.</p>
<h3 id="7-mrunit-엠알유닛">7. Mrunit (엠알유닛)</h3>
<p>맵리듀스를 테스트 하는 프레임워크이다.</p>
<h3 id="8-oozie우지">8. Oozie(우지)</h3>
<p>데이터를 시 용도에 맞게 데이터 마트를 만들 때, 중간중간에 있는 workflow들을 관리해 준다. 즉, Oozie는 단순히 스케줄러의 작업을 수행하므로 작업을 예약하고 단일 단위로 함께 바인딩한다.</p>
<h3 id="9-yarnyet-another-resource-negotiator">9. YARN(Yet Another Resource Negotiator)</h3>
<p>YARN은 Hadoop v1에 있던 <strong>Job Tracker의 병목현상을 제거</strong>하기 위해 Hadoop v2에 도입이 되었다. 클러스터 전체에서 리소스를 관리하고 하둡 시스템에 대한 스케줄링 및 리소스 할당을 수행함으로 *<em>YARN은 빅데이터 처리에 사용되는 대규모 분산 운영체제 *</em>라고도 할 수 있다.</p>
<p>YARN은 또한 <strong>그래프 처리, 대화형 처리, 스트림 처리 및 배치 처리</strong>와 같은 <strong>다양한 데이터 처리 엔진</strong>을 통해 HDFS (Hadoop 분산 파일 시스템)에 저장된 데이터를 실행하고 처리 할 수 있기 때문에 시스템을 훨씬 더 효율적으로 만든다. 다양한 구성 요소를 통해 <strong>다양한 리소스를 동적으로 할당</strong>하고 <strong>응용 프로그램 처리를 예약</strong> 할 수 있다. </p>
<h3 id="10-solr-lucene">10. Solr, Lucene</h3>
<p>자바 라이브러리의 도움으로 검색 및 인덱싱 작업을 수행하는 두 서비스이다.</p>
<h3 id="11-spark">11. Spark</h3>
<p><strong>일괄 처리, 반복적 실시간 처리, 그래프 변환 및 시각화 등</strong>과 같은 <strong>소모적인 프로세스 작업을 처리하는 플랫폼</strong>이다. 메모리 리소스를 소비하므로 최적화 측면에서 이전보다 빠르다. <strong>Spark는 실시간 데이터에 가장 적합</strong>한 반면, <strong>Hadoop은 구조화 된 데이터 또는 일괄 처리</strong>에 가장 적합하다. 따라서 대부분의 회사에서는 두가지 다 변환해가면서 사용되어진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[맵리듀스]]></title>
            <link>https://velog.io/@under_the_sky/%EB%A7%B5%EB%A6%AC%EB%93%80%EC%8A%A4</link>
            <guid>https://velog.io/@under_the_sky/%EB%A7%B5%EB%A6%AC%EB%93%80%EC%8A%A4</guid>
            <pubDate>Wed, 05 Jul 2023 05:30:18 GMT</pubDate>
            <description><![CDATA[<p>이번에는 <strong>맵리듀스</strong>에 대해서 알아보자 </p>
<blockquote>
<p>하둡은 <strong>분산처리가 가능한 시스템</strong>과 <strong>분산되어 저장된 데이터</strong>를 <strong>병렬로 처리가능</strong>하게 하는 <strong>맵리듀스 프레임워크의 결합한 단어</strong>라 할 수 있다. </p>
</blockquote>
<p>즉, <strong>하둡 분산 파일 시스템(HDFS)</strong>은 대용량 파일을 <strong>지리적으로 분산되어 있는 수많은 서버에 저장하는 솔루션</strong>이며, <strong>맵-리듀스</strong>는 <strong>분산되어 저장된 대용량 데이터</strong>를 <strong>병렬로 처리하는 솔루션</strong>이다.</p>
<p><strong>맵리듀스</strong>는 <strong>대용량 데이터 처리를 위한 분산 프로그래밍 모델</strong>이다. <strong>분산되어 있는 데이터</strong>를 분석하려고 한다. 이때 분산된 데이터를 <strong>굳이 한 곳으로 모아서 분석</strong>을 한다면, 굉장히 <strong>오래걸리고 비효율적</strong>일 것이다. 따라서 <strong>특정 데이터를 가지고 있는 데이터 노드</strong>만 <strong>분석을 하고 결과만 받는 것</strong>이 맵리듀스이다. <strong>통합분석이 아닌, 개별분석 후 결과를 취합</strong>한다고 생각하자.</p>
<blockquote>
<p>예를 들어보면, 100개의 자료를 한 명이 보는 것 보다 100명이 하나씩 보는 것이 훨씬 빠르다. 이것이 분산처리의 핵심인데, 만약 여기서 하나의 자료의 크기가 다르거나, 정확한 일의 배분이 힘들 경우를 해결해 주는 역할이 맵리듀스의 역할이라고 할 수 있다.</p>
</blockquote>
<hr>
<p>맵리듀스는 Map단계와 Reduce단계로 이루어져 있다.</p>
<h3 id="map단계">MAP단계</h3>
<p>Map은 분산되어있는 컴퓨터에서 처리하는 것이다.</p>
<p>Map단계에서는 <strong>흩어져 있는 데이터</strong>를 <strong>key, value</strong>로 데이터를 묶어준다.</p>
<p><strong>key는 몇 번째 데이터인지, value는 값을 추출한 정보야.</strong> 예를 들면, &#39;빅데이터&#39;가 key라면 value는 빅데이터라는 키가 몇번 나오는지 숫자가 적혀있는 것이지.</p>
<p>이러한 방식으로 <strong>분산되어 있는 컴퓨터</strong>에서 각각 <strong>key와 value</strong>를 구하게 돼. 구한 후에는 통합하기 위해 통합하는 곳(Reduce)으로 보내주게 된다.</p>
<p>정리하면, Map은 <strong>흩어져 있는 데이터</strong>를 <strong>Key, Value의 형태의 연관성 있는 데이터 분류로 묶는 작업</strong>이다.</p>
<h3 id="reduce단계">Reduce단계</h3>
<p><strong>최종적인 통합관리</strong>를 위해 <strong>Reduce</strong>를 해주는 것이 Reduce 단계이다.</p>
<p>만약 A컴퓨터에서 빅데이터가 5번나오고 B컴퓨터에서 빅데이터가 10번 나왔다면, Reduce는 빅데이터가 총 15번 나왔다고 통합을 해주는 것이지. <strong>통합이라는 자체가 줄여주는 의미</strong>가 있기 때문에 <strong>Reduce</strong>라고 쓰이는 것이다.</p>
<p><strong>Reduce단계</strong>는 <strong>Map단계의 key를 중심으로 필터링 및 정렬</strong>한다. 하둡에서는 이 <strong>Map과 Reduce</strong>를 함수를 통해서 구현하고 맵리듀스 잡을 통해 제어한다.</p>
<p>정리하면 <strong>Reduce</strong>는 <strong>Filtering과 Sorting</strong>을 거쳐 <strong>데이터를 추출, Map 작업 중 중복데이터를 제거하고 원하는 데이터를 추출하는 작업</strong>이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HDFS]]></title>
            <link>https://velog.io/@under_the_sky/HDFS</link>
            <guid>https://velog.io/@under_the_sky/HDFS</guid>
            <pubDate>Wed, 05 Jul 2023 04:56:06 GMT</pubDate>
            <description><![CDATA[<p>HDFS 구조(Architecture) 
기본적으로 HDFS는 마스터 슬레이브 구조야</p>
<blockquote>
<p><strong>마스터 슬레이브 구조</strong>
마스터/슬레이브(Master/slave)는 장치나 프로세스(마스터)가 하나 이상의 다른 장치나 프로세스(슬레이브)를 통제하고 통신 허브 역할을 하는 비대칭 통신 및 제어 모델을 의미한다</p>
</blockquote>
<p>아래의 그림처럼 분산처리 시스템이기 때문에 MapReduce와 HDFS는 기본적으로 Master와 Slave의 관점으로 구분이 돼. 쉽게 말하면, 분산되어져 있는 것들을 관리할 master가 필요하다고 생각하면 좋을 것 같아. 즉, 일을 시킬 컴퓨터가 하나는 있어야해.</p>
<p><img src="https://velog.velcdn.com/images/under_the_sky/post/21f7d405-9989-4bfa-b9c3-06df8c1aa568/image.png" alt=""></p>
<p>MapReduce는 일을 어떻게 나눠서 수행하는지를 Master에서 관리하고, HDFS는 저장 시 어떻게 분산 저장할 지를 Master에서 관리하는거지. </p>
<p>HDFS는 마스터 슬레이브 구조로 <strong>하나의 네임노드</strong>와 <strong>여러 개의 데이터노드</strong>로 구성되어 있어. 네임노드는 메타데이터를 가지고 있고, 데이터는 블록 단위로 나누어 데이터노드에 저장돼. 데이터를 읽고 쓰려면 사용자는 메타데이터를 가지고 있는 네임노드를 이용하면 되는거지.</p>
<p>네임노드, 데이터노드, 블록에 대해 하나씩 알아보도록 하자.</p>
<hr>
<h3 id="네임노드namenode"><strong>네임노드(namenode)</strong></h3>
<blockquote>
<p>네임노드는 분산 처리 시스템에서 Master를 담당하며, 메타데이터 관리와 데이터노드를 관리한다.</p>
</blockquote>
<p><strong>네임노드</strong>는 각 데이터노드에서 전달하는 메타데이터를 받은 후에 전체 노드의 메타데이터 정보와 파일 정보를 묶어서 관리해. 즉 파일 시스템을 유지하기 위해 메타데이터를 관리하는거지</p>
<p>데이터를 저장할 시에 기본적으로 <strong>블록단위</strong>로 들어오게 되는데, 이때 들어온 블록들을 어느 <strong>데이터노드에서 저장</strong> 할 지를 정해준다고 이해하자.</p>
<p>데이터노드는 실제로 데이터를 저장하는 컴퓨터기 때문에 에러가 날 수도 있어. 따라서 네임노드와 데이터 노드는 3초마다 <strong>하트비트(heartbeat)</strong>를 주고 받아. 
쉽게 말하면 <strong>데이터 노드에서 살아있다고 네임노드에 문서를 보내 알려주는 것</strong>이야. 이러한 알림을 3초마다 보내기 때문에, 알림이 안오면 문제가 생겼다고 판단해. 이러한 문제가 생긴다면 <strong>다른 데이터 노드에 복제된 블럭을 가지고 와서 사용</strong>할 수 있어.</p>
<h3 id="메타데이터"><strong>메타데이터</strong></h3>
<p> 메타데이터는 <strong>전체적인 구조</strong>를 나타내. 그리고 메타데이터는 파일이름, 파일크기, 파일생성시간, 파일접근권한, 파일 소유자 및 그룹 소유자, 파일이 위치한 블록의 정보 등으로 구성돼. 저장위치는 사용자가 설정한 위치(dfs.name.dir)에 저장돼.</p>
<h3 id="데이터노드datanode"><strong>데이터노드(datanode)</strong></h3>
<p> 데이터노드는 <strong>데이터들이 저장되는 컴퓨터</strong>야. 데이터노드는 파일을 저장하는 역할을 하고, 이때 파일은 <strong>블록단위로</strong> 저장돼. 데이터노드는 주기적으로 네임노드에 <strong>하트비트와 블록리포트</strong>를 전달해.</p>
<blockquote>
<p><strong>하트비트</strong> : 데이터노드의 동작여부를 판단하는데 이용되고, 네임노드에서는 하트비트가 전달되지 않는 데이터노드는 동작하지 않는 것으로 판단하여 더이상 데이터를 저장하지 않도록 설정한다.
<strong>블록리포트</strong> :  블록의 변경사항을 체크하고, 네임노드의 메타데이터를 갱신한다. 블록파일은 사용자가 설정한 위치(dfs.data.dir)에 저장된다.</p>
</blockquote>
<h3 id="데이터노드의-상태"><strong>데이터노드의 상태</strong></h3>
<p>데이터노드는 상태를 나타내는 정보로 <strong>활성상태</strong>와 <strong>운영상태</strong>를 확인할 수 있어.</p>
<p><strong>활성상태</strong></p>
<blockquote>
<p><strong>데이터노드가 Live, Dead 상태인지를 나타낸다.</strong> 데이터노드가 하트비트를 통해 활성 상태가 확인이 되면 Live 상태이다. 만약 문제가 발생하여 지정 시간동안 하트비트를 받지 못하면 네임노드는 데이터 노드의 상태를 Stale 상태로 변경하고, 그 이후에도 지정한 시간동안 응답이 없으면 Dead 노드로 변경한다.</p>
</blockquote>
<p><strong>운영상태</strong></p>
<blockquote>
<p><strong>운영 상태는 보통 데이터 노드의 업그레이드나 작업을 하기 위해 서비스를 잠시 멈추어야 할 경우 블록을 안전하게 보관하기 위해 설정한다.</strong> 운영상태의 종류에는 아래와 같다.</p>
</blockquote>
<pre><code>NORMAL    서비스 상태
DECOMMISSIONED    서비스 중단 상태
DECOMMISSION_INPROGRESS    서비스 중단 상태로 진행 중
IN_MAINTENANCE    정비 상태
ENTERING_MAINTENANCE    정비 상태로 진행 중</code></pre><h3 id="네임노드의-구동-과정"><strong>네임노드의 구동 과정</strong></h3>
<p>기본적으로 네임노드는 Fsimage와 Edits를 읽어서 작업을 처리해.</p>
<p>먼저 <strong>Fsimage를 읽어서 메모리에 적재</strong>한 후에 <strong>Edits 파일을 읽어와서 변경내역을 반영</strong>시키고, <strong>현재의 메모리 상태를 반영</strong>하여 <strong>Fsimage 파일을 생성</strong>하는거지. 데이터 노드로부터 블록리포트를 수신하여 매핑정보를 생성하고 서비스를 시작할 수 있어.</p>
<h3 id="hdfs-파일-사용">HDFS 파일 사용</h3>
<blockquote>
<p>HDFS의 파일에 대한 내용을 위에서 배웠다. 그렇다면, 내부의 파일을 사용하는 법에 대해 알아보자.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/under_the_sky/post/873075d6-f884-4b70-b5aa-d2dcead7e4ab/image.png" alt="">
HDFS의 파일을 읽는 순서는 아래와 같다.</p>
<blockquote>
<ol>
<li>open() 명령어를 통해 DistributedFileSystem에 있는 FileSystem의 파일을 연다</li>
<li>RPC()를 NameNode를 호출하여 저장되어있는 블록이 저장된 DataNode의 주소를 받는다. </li>
<li>DistributedFileSystem은 client가 데이터를 검색할 수 있도록 검색을 지원하는 입력 스트림인 FSDataInputStream를 client에게 준다. 그러면 그것을 통해 찾고자 하는 datanode와 DFSInputStream이 맵핑된다. 그리고 검색후 read() 명령어를 통해 호출을한다.</li>
<li>datanode 주소가 저장된 DFSInputStream은 datanode와 연결되고, 데이터는 datanode에서 클라이언트로 가게된다. 이러한 형식으로 반복 read()가 호출하여 파일을 읽는다.</li>
<li>블록 끝에 도달하면 DFSInputStream은 데이터 노드에 대한 열결을 닫고, 다음 블록에 가장 접합한 데이터 노드를 찾는다.</li>
<li>읽기가 마치면 FSDataInputStram에서 close()를 호출한다.</li>
</ol>
</blockquote>
<pre><code>RPC : remote procedure call, 은 별도의 원격 제어를 위한 코딩 없이 
    다른 주소공간에서 함수나 프로시저를 실행할 수 있게하는 프로세스 간 통신 기술</code></pre><h3 id="블록">블록</h3>
<p>Hadoop의 HDFS는 파일을 데이터 블록이라고 하는 <strong>작은 크기의 블록으로 나눠서</strong> 사용해. </p>
<p>HDFS는 <strong>지정한 크기의 블록</strong>으로 나누어 지고 각각 독립적으로 저장해. </p>
<p>만약 지정한 크기보다 <strong>작은 파일은 실제 파일 크기의 블록으로 저장</strong>되고, 지정 크기보다 <strong>크다면 나눠서 저장</strong>시켜.</p>
<p>따라서 파일의 모든 블록은 <strong>마지막 블록을 제외하고는 동일한 크기</strong>가 돼.</p>
<blockquote>
<p>HDFS 데이터 블록은 기본적으로 검색 및 네트워크 트래픽 비용을 줄여준다. 기본적으로는 128MB의 크기의 덩이리이며, 크기는 재설정 가능하다. </p>
</blockquote>
<h3 id="hdfs-federation">HDFS Federation</h3>
<p><strong>HDFS Federation</strong>은 디렉토리 단위로 네임노드를 등록하여 사용하는 것으로, 파일이 많아짐에 따른 메모리 관리 문제를 해결하기 위해 하둡 v2 부터 지원됐어.</p>
<blockquote>
<p>예를 들어 user, hadoop, tmp 세개의 디렉토리가 존재할 때, /user, /hadoop, /tmp 디렉토리 단위로 총 3개의 네임노드를 실행하여 파일을 관리하게 해. 각각 독립적으로 관리하기 때문에 하나의 문제가 발생하더라도, 다른 네임노드에 영향을 주지 않아.</p>
</blockquote>
<h3 id="hdfs-high-availability고가용성">HDFS High Availability(고가용성)</h3>
<p>네임노드에 문제가 발생하면 모든 작업이 중지되고, 파일을 읽거나 쓸 수 없게 돼. 하둡 v2에서 이 문제를 해결하기 위해서 <strong>HDFS High Availability</strong>을 제공하고 있어. </p>
<p>HDFS 고가용성(Hight Availability)은 이중화된 두대의 서버인 <strong>액티브(active) 네임노드</strong>와 <strong>스탠바이(standby) 네임노드</strong>를 이용하여 지원해. <strong>액티브 네임노드</strong>와 <strong>스탠바이 네임노드</strong>는 데이터 노드로부터 <strong>블록 리포트와 하트비트</strong>를 모두 받아서 <strong>동일한 메타데이터를 유지</strong>하고, 공유 스토리지를 이용하여 <strong>에디트파일을 공유</strong>한다.</p>
<blockquote>
<p><strong>액티브 네임노드</strong>는 네임노드의 역할을 수행한다.
<strong>스탠바이 네임노드</strong>는 액티브 네임노드와 동일한 메타데이터 정보를 유지하다가, 액티브 네임노드에 문제가 발생하면 스탠바이 네임노드가 액티브 네임노드로 동작한다.</p>
</blockquote>
<p><strong>액티브 네임노드</strong>에 문제가 발생하는 것을 자동으로 확인하는 것이 어렵기 때문에 보통 주키퍼를 이용하여 장애 발생시 자동으로 스탠바이 네임노드로 변경될 수 있도록 하고 있어. </p>
<p><strong>스탠바이 네임노드</strong>는 세컨더리 네임노드의 역할을 동일하게 수행하기 때문에, HDFS를 고가용성 모드로 설정하였을 때는 세컨더리 네임노드를 실행하지 않아도 괜찮아. 만약 고가용성 모드에서 세컨더리 네임노드를 실행하면 오류가 발생하게 돼.</p>
<h3 id="hdfs-safemode">HDFS safemode</h3>
<blockquote>
<p>safemode는 일기 전용 상태로 데이터 노드 수정이 불가능해서, 데이터의 추가, 수정, 복제가 일어나지 않는다. 보통 safemode는 노드에 문제가 생겼거나 서버 운영 정비를 위해 설정을 한다.</p>
</blockquote>
<h3 id="hdfs-휴지통">HDFS 휴지통</h3>
<blockquote>
<p>휴지통 기능이 설정되면 HDFS에서 삭제한 파일은 바로 삭제되지 않고, 각 사용자의 홈디렉토리 아래 휴지통 디렉토리(/user/유저명/.Trash)로 이동된다. </p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[하둡이란]]></title>
            <link>https://velog.io/@under_the_sky/%ED%95%98%EB%91%A1%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@under_the_sky/%ED%95%98%EB%91%A1%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Wed, 05 Jul 2023 04:11:19 GMT</pubDate>
            <description><![CDATA[<p>아파치 하둡은 <strong>대량의 자료를 처리할 수 있는 큰 컴퓨터 클러스터</strong>에서 동작하는 <strong>분산 응용 프로그램</strong>을 지원하는 프리웨어 자바 소프트웨어 프레임워크야.</p>
<blockquote>
<p><strong>Hadoop (High-Availability Distributed Object-Oriented Platform)</strong>
 자바 소프트웨어 프레임워크로 대량의 자료(빅데이터)의 분산 저장과 분석을 위한 분산 컴퓨팅 솔루션이다. 일반적으로 하둡파일시스템(HDFS)과 맵리듀스(MapReduce)프레임워크로 시작되었으나, 여러 데이터저장, 실행엔진, 프로그래밍 및 데이터처리 같은 하둡 생태계 전반을 포함하는 의미로 확장 발전 되었다. 한문장으로 정리하면, 데이터의 양이 너무 많으니 분산해서 저장한다는 의미이다.</p>
</blockquote>
<p><strong>하둡에서의 빅데이터</strong>
빅데이터란 한대의 컴퓨터로는 <strong>저장하거나 연산하기 어려운 규모의 거대 데이터</strong>를 의미해. 따라서 빅데이터 같은 경우는 <strong>여러대의 컴퓨터로 나눠서 일을 처리</strong>해야하지. 이를 분산이라고 해. 또한 큰 데이터를 한번에 저장하기는 힘들어. 이러한 데이터를 알아서 <strong>여러대의 컴퓨터에 나눠서 저장해주고, 필요시 알아서 불러오는 시스템</strong>이 하둡인거지. 같은 내용을 중복되게 저장을 하기 때문에 손실되더라도 복구가 가능해. 이러한 하둡의 장점은 <strong>분석 시 나눠서 데이터를 분석하고 합치면 돼서 매우 빠르다는 점이야</strong>. 하지만 <strong>저장된 데이터를 변경하는 것이 불가능</strong>하고, <strong>실시간 데이터와 같은 신속한 작업에서는 부적합</strong>하다고 볼 수 있어.</p>
<p>정형데이터 뿐만 아니라 비정형데이터도 사용이 가능하기 때문에, 모든 분야에서도 활용가능하다고 할 수 있어.</p>
<p><strong>하둡의 동작흐름은 다음과 같아.</strong>
데이터가 들어오면, 데이터를 쪼개. 그리고 그 데이터를 분리해서 저장하지. 따라서 데이터를 쪼갠 후에 <strong>어느 데이터 노드에 저장이 되어 있는지를 기록해 놓는 부분(메타데이터)이 필요해</strong>. 정리하면, 하둡에서 데이터를 저장하기 전에 <strong>네임노드에서 분산을 하고 저장위치를 분배해</strong>. 그 후에 여러 개 중에 지정된 데이터 노드에 저장을 한다고 간단히 이해할 수 있어.</p>
<p><strong>하둡의 중요한 기능인 HDFS와 맵리듀스에 대해 알아보자</strong></p>
<h3 id="hdfs란">HDFS란?</h3>
<blockquote>
<p> 하둡 분산형 파일시스템(HDFS)는 하둡 네트워크에 연결된 기기에 데이터를 저장하는 분산형 파일시스템으로 실시간 처리보다는 배치처리를 목적으로 설계되었다. 따라서 작업량이 작거나 빠른 데이터 응답이 필요한 작업에서는 적합하지 않다.</p>
</blockquote>
<p>기본적으로 HDFS는 데이터를 블록 단위로 나누어 저장해. 따라서 큰 데이터를 나누어 저장하므로 단일 디스크 보다 큰 파일도 저장이 가능해. 만약 블록단위가 256MB라면 1G파일은 4개의 블록으로 나누어 저장돼. 블록단위보다 작은 크기의 파일이라면 파일을 나누지 않고 그대로 저장할 수 있어.</p>
<p>블록에 문제가 생겨 데이터가 손실되는 경우를 막기 위해 HDFS는 각 블록을 복제하여 중복으로 저장해. 즉, 하나의 블록은 3개의 블록으로 복제되어 저장되는거지. 따라서 1G 데이터를 저장할 때 3G의 저장공간이 필요하다고 할 수 있어.</p>
<p>참고로 HDFS는 읽기 중심을 목적으로 만들어 졌기 때문에 파일의 수정은 지원하지 않아. (읽는 속도를 높인다.)</p>
<p>맵리듀스는 HDFS의 데이터의 지역성을 이용해서 처리 속도를 증가시켜. 데이터를 처리할 때 데이터를 알고리즘이 있는 곳으로 이동시켜 처리하지 않고, 데이터의 위치에서 알고리즘을 처리하여 데이터를 이동시키는 비용을 줄일 수 있지.</p>
<p>HDFS는 다음 글에서 자세히 알아보자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스 관리 시스템(DBMS)]]></title>
            <link>https://velog.io/@under_the_sky/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B4%80%EB%A6%AC-%EC%8B%9C%EC%8A%A4%ED%85%9CDBMS</link>
            <guid>https://velog.io/@under_the_sky/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EA%B4%80%EB%A6%AC-%EC%8B%9C%EC%8A%A4%ED%85%9CDBMS</guid>
            <pubDate>Wed, 05 Jul 2023 02:40:45 GMT</pubDate>
            <description><![CDATA[<p>이전에 파일시스템의 단점을 보완하여 데이터베이스 시스템이 등장했다고 했어.</p>
<p><strong>DBMS는 이 데이터베이스 시스템을 관리해주는 관리 시스템이야.</strong> 
즉 데이터베이스 관리 시스템(DataBase Management System, DBMS)은 데이터베이스를 조작하는 별도의 소프트웨어라고 할 수 있어.</p>
<p>그렇다면 DBMS는 무슨 역할(기능)을 해줄까?</p>
<p><strong>데이터베이스 관리 시스템의 기능은 크게 구성(정의), 조작, 제어 기능으로 나눌 수 있어.</strong></p>
<blockquote>
<ul>
<li><strong>구성(정의) 기능</strong>: 데이터베이스에 저장될 자료의 구조와 응용 프로그램이 이 구조를 이용하는 방식을 정의하는 기능. 레코드 구조의 정의, 데이터 모형의 정의, 물리적 구조의 정의 등을 포함한다.</li>
</ul>
</blockquote>
<ul>
<li><strong>조작 기능</strong>: 사용자의 요구에 따라 데이터베이스에 접근하여 저장된 자료를 검색, 갱신, 삽입, 삭제할 수 있도록 하는 기능. 사용자들은 쉽고, 명확하고 효율적인 데이터 언어(data language)로 데이터베이스의 데이터를 조작할 수 있다.</li>
<li><strong>제어 기능</strong>: 사용자가 데이터를 조작하려는 작업이 데이터 무결성(data integrity)을 파괴하지 않도록 작업 요청을 제어하는 기능. 접근하는 사용자의 권한을 검사하여 보안을 유지하며, 여러 사용자가 데이터베이스에 동시에 접근하여 데이터를 처리할 경우 처리 결과가 항상 정확성을 유지하도록 한다.</li>
</ul>
<p>구성(정의) 기능은 <strong>데이터 베이스에 대한 설계</strong>와 관련되고,
조작 기능은 <strong>쿼리를 통한 자료에 대한 조작</strong>, 
제어 기능은 데이터 포맷에 대한 안전성, 그리고 보안에 대한 의미를 지니고 있어</p>
<p><img src="https://velog.velcdn.com/images/under_the_sky/post/9e7328ee-6b86-4f0e-aca1-2f4b1b1287da/image.png" alt=""></p>
<p>대표적인 DBMS로는 Oracle, MySQL, MariaDB등이 있어.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파일시스템과 데이터베이스]]></title>
            <link>https://velog.io/@under_the_sky/%ED%8C%8C%EC%9D%BC%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@under_the_sky/%ED%8C%8C%EC%9D%BC%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BC-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Wed, 05 Jul 2023 02:20:42 GMT</pubDate>
            <description><![CDATA[<p>데이터를 저장하는 방법에는 여러가지 존재하지만 과거에는 파일시스템으로 저장을 했었어.</p>
<p><img src="https://velog.velcdn.com/images/under_the_sky/post/207447ae-17ba-4bfe-996a-1cd775f41b1c/image.png" alt="">
<strong>파일 시스템</strong>은 파일(데이터의 모임)을 저장 장치에 저장하고 사용하기 위한 일종의 규칙이나 체계를 뜻해.</p>
<p>파일의 이름을 붙이고, 쉽게 파일에 접근할 수 있도록 배치를 신경 쓰는 등 파일과 관련된 기능을 수행하는 시스템이지</p>
<p>파일의 기본적인 구성요소는 순차적인 레코드들이고, 레코드는 파일을 다룰 때 실제로 읽고 쓰는 단위로서 사용되는 데이터 단위를 뜻하지.</p>
<p><strong>이와 같은 파일시스템에는 특징들이 있어</strong>
파일 시스템에서는 파일에 접근하는 방식이 응용 프로그램 내에 표현되기 때문에 <strong>응용 프로그램과 데이터 간의 의존관계</strong>가 존재하게 되지.</p>
<p>그래서 <strong>데이터의 구조, 접근 방법</strong>이 변경되면 <strong>기존의 프로그램과 데이터를 함께 변경</strong>해야만 하지. 즉, 데이터 정의가 응용 프로그램에 내포되어 있다는 거야.
또, 프로그램에서 데이터를 접근하고 조작하는 것 이외에 별도의 제어가 없어</p>
<p><strong>위와 같은 파일 시스템의 요인이 여러 문제들을 발생시켜</strong></p>
<blockquote>
<p>▶ <strong>데이터 간 불일치가 발생할 수 있다.</strong>
중복된 데이터의 변경을 제어하는 것이 어렵기 때문에 여러 개의 중복 데이터 중 일부의 데이터만 변경된다고 하면, 중복된 데이터 간에 불일치가 발생할 수 있습니다.
▶ <strong>다수 사용자를 위한 동시성 제어가 제공되지 않는다.</strong>
두 사용자가 동시에 파일에 접근할 때 각 사용자가 혼자서 데이터베이스를 접근하는 것처럼 인식하도록 하는 동기화가 되지 않습니다.
▶ <strong>쉬운 질의어가 제공되지 않는다.</strong>
SQL 같은 쉬운 질의어가 제공되지 않는다.
▶ <strong>보안 기능이 미흡하다.</strong>
파일 시스템에서는 파일 단위로만 검색, 갱신, 실행 권한을 부여할 수 있어서 사용자의 권한에 따른 세밀한 접근 제어(레코드 단위)를 시행하기 어렵다.
▶ <strong>회복 기능이 없다.</strong>
응용 프로그램에서 파일 내의 데이터를 수정하는 도중에 강제로 파일이 닫히는 등의 사고가 발생했을 때 데이터를 복구하는 기능이 없습니다.
▶ <strong>데이터 독립성이 없어 유지보수 비용이 크다.</strong>
파일의 구조가 응용 프로그램에 반영되어 있기 때문에 파일의 구조가 바뀌면 영향을 받는 모든 응용 프로그램들을 수정해야 한다.
또한 응용 프로그램의 기능을 확장하려면 파일의 구조에 대한 요구 사항이 바뀌므로 파일을 재조직해야 한다.
유지보수에 대한 비용이 상당히 높다.
▶ <strong>데이터 모델링 개념이 부족하다.</strong>
단순히 순차적인 레코드만으로 나타내기 때문에 데이터의 의미와 데이터 간의 상호 관계를 나타내기 힘들다.
▶ <strong>데이터 무결성을 유지하기가 어렵다.</strong>
파일 내의 데이터가 만족시켜야 하는 무결성 제약조건들을 명시하려면 프로그래머가 직접 프로그래밍 언어를 사용하여 일일이 프로그램에 표현해야 하므로 데이터 무결성을 유지하기가 어렵다.
또한 새로운 제약조건들을 추가하거나 기존의 제약조건을 수정하는 것도 어렵다.
▶ <strong>생산성이 낮다.</strong>
각 응용 프로그램마다 프로그래머가 새로운 파일 형식과 설명을 설계하는 과정부터 시작한 후 새로운 응용 프로그램을 위한 파일 접근 논리를 작성해야 하기 때문에 개발 시간이 오래 걸린다.
프로그래머는 자바, C 등의 프로그래밍 언어로 원하는 데이터 및 원하는 데이터를 찾는 방법을 상세하게 구현해야 한다.
▶ <strong>데이터 공유가 잘 되지 않는다.</strong>
각 응용 프로그램마다 파일들을 갖고 있으며 데이터를 접근하는 응용 프로그램들이 여러 가지 프로그래밍 언어들로 작성되어 데이터 공유가 제한된다.</p>
</blockquote>
<p><strong>이렇게 많은 단점들을 보완하기 위해 데이터베이스 시스템이 등장해</strong>
파일 시스템의 단점을 보완하면서 나온게 데이터베이스 시스템이라 위와 같은 단점들을 해결한게 데이터베이스의 장점이라고 볼 수 있어.</p>
<p><strong>무조건 데이터베이스 시스템을 사용해야하진 않아</strong>
데이터베이스 시스템의 소프트웨어의 규모가 크고 복잡해서 파일방식보다 많은 하드웨어 자원을 필요로 하므로 추가적인 하드웨어 구입 비용이 들 수도 있고, DBMS 자체의 구입 비용과 유지, 보수 비용도 상당히 비싼 편이야.
또, DBMS가 자동적으로 데이터베이스의 일관성을 유지하기 위해서 컴퓨터의 자원을 많이 필요로 하므로 응답 시간이 많이 걸릴 수도 있어.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컴퓨터 구조] 명령어 사이클과 인터럽트]]></title>
            <link>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%82%AC%EC%9D%B4%ED%81%B4%EA%B3%BC-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8</link>
            <guid>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%82%AC%EC%9D%B4%ED%81%B4%EA%B3%BC-%EC%9D%B8%ED%84%B0%EB%9F%BD%ED%8A%B8</guid>
            <pubDate>Mon, 03 Jul 2023 15:50:28 GMT</pubDate>
            <description><![CDATA[<p>CPU가 하나의 명령어를 처리하는 과정에는 어떤 정해진 흐름이 있고, CPU는 그 흐름을 반복하며 명령어들을 처리해나가. 이렇게 <strong>하나의 명령어를 처리하는 정형화된 흐름</strong>을 <strong>명령어 사이클</strong>이라고 해.</p>
<p>CPU는 정해진 흐름에 따라 명령어를 처리해 나가지만, 간혹 이 흐름이 끊어질 때도 있어. 이를 <strong>인터럽트</strong>라고 해.</p>
<h3 id="명령어-사이클이란-뭘까">명령어 사이클이란 뭘까?</h3>
<p>우리가 실행하는 프로그램은 수많은 명령어로 이루어져 있고, CPU는 이 명령어들을 하나씩 실행해.
이때 프로그램 속 각각의 명령어 들이 일정한 주기가 반복되며 실행되는데 이 주기를 명령어 사이클이라고 해.</p>
<p>명령어 사이클은 1.인출 사이클, 2.실행 사이클, 3.간접 사이클로 나뉘어.</p>
<blockquote>
<p><strong>1. 인출 사이클</strong>: 메모리에 저장된 명령어를 메모리에서 CPU로 가져오는 과정 
<strong>2. 실행 사이클</strong>: CPU로 가져온 명령어를 실행하는 단계. 제어장치가 명령어 레지스터에 담긴 값을 해석하고, 제어 신호를 발생시키는 단계가 실행 사이클.
<strong>3. 간접 사이클</strong>: 간접 주소 방식 등으로 메모리에 한번 더 접근해야 하는 과정.</p>
</blockquote>
<p><strong>그러나 명령어 사이클은 인터럽트를 고려해야해</strong></p>
<h3 id="인터럽트란-뭘까">인터럽트란 뭘까?</h3>
<p>인터럽트는 <strong>CPU가 수행 중인 작업을 방해하는 신호</strong>야. CPU가 작업을 잠시 중단해야할 정도라면 인터럽트는 &quot;CPU가 꼭 주목해야할 때&quot;, &quot;CPU가 얼른 처리해야 할 다른 작업이 생겼을 때&quot; 발생하지.</p>
<p>인터럽트는 크게 동기 인터럽트와 비동기 인터럽트로 나뉘어</p>
<h4 id="동기-인터럽트예외">동기 인터럽트(예외)</h4>
<p>동기 인터럽트는 CPU에 의해 발생하는 인터럽트야.
주로 CPU가 명령어를 수행하다가 <strong>예상치 못한 상황에 마주쳤을 때</strong>나, CPU가 실행하는 <strong>프로그래밍 상에서 오류</strong>와 같은 예외적인 상황에 마주쳤을 때 발생하지.</p>
<h4 id="비동기-인터럽트하드웨어-인터럽트">비동기 인터럽트(하드웨어 인터럽트)</h4>
<p>비동기 인터럽트는 주로 입출력 장치에 의해 발생하는 인터럽트야. 예를 들어 세탁기 완료 알림, 전자레인지 조리 완료 알림과 같은 알림 역할을 해</p>
<blockquote>
<p><strong>프린터</strong>
CPU가 프린터와 같은 입출력 장치에 입출력 작업을 부탁하면 작업을 끝낸 입출력 장치가 CPU에 완료 알림(인터럽트)를 보내.</p>
</blockquote>
<blockquote>
<p><strong>키보드, 마우스</strong>
키보드, 마우스와 같은 입출력 장치가 어떠한 입력을 받아들였을 때, 이를 처리하기 위해 CPU에 입력 알림(인터럽트)를 보내.</p>
</blockquote>
<p>하드웨어 인터럽트를 이용하면 CPU는 프린터로부터 프린트 완료 인터럽트를 받을 때까지 다른 작업을 처리할 수 있어.</p>
<p>입출력 작업 중에도 CPU로 하여금 효율적으로 명령어를 처리할 수 있게 만들지.</p>
<h4 id="하드웨어-인터럽트-처리순서">하드웨어 인터럽트 처리순서</h4>
<blockquote>
<ol>
<li>입출력 장치가 CPU에 <strong>인터럽트 요청 신호</strong>를 보냄.</li>
<li>CPU는 실행 사이클이 끝나고 <strong>명령어를 인출하기 전 항상 인터럽트 여부</strong>를 확인</li>
<li>CPU는 인터럽트 요청을 확인하고 <strong>인터럽트 플래그</strong>를 통해 <strong>현재 인터럽트를 받아들일 수 있는지 여부</strong>를 확인</li>
<li>인터럽트를 받아들일 수 있다면 CPU는 <strong>지금까지의 작업을 백업</strong>함.</li>
<li>CPU는 인터럽트 벡터를 참조하여 <strong>인터럽트 서비스 루틴</strong>을 실행</li>
<li>인터럽트 서비스 루틴 실행이 끝나면 4에서 <strong>백업해둔 작업을 복구하여 실행을 재개</strong>함.</li>
</ol>
</blockquote>
<p>CPU가 인터럽트 요청을 수용하기 위해서는 <strong>플래그 레지스터</strong>의 <strong>인터럽트 플래그</strong>가 <strong>활성화</strong> 되어있어야 해.</p>
<p>인터럽트 플래그가 <strong>&#39;가능&#39;, &#39;불가능&#39;</strong> 어떻게 설정 되어있냐에 따라 인터럽트를 처리한다는 거지.</p>
<p>그러나 <strong>인터럽트 플래그로 막을 수 없는 하드웨어 인터럽트</strong>도 있어. 즉 &#39;막을 수 있는 인터럽트&#39;, &#39;막을 수 없는 인터럽트&#39;로 나뉘어. 정전이나 하드웨어 고장으로 인한 인터럽트가 못막는 인터럽트야.
<img src="https://velog.velcdn.com/images/under_the_sky/post/a57e5cfe-ea68-4c92-b603-cfc7e44dd33f/image.png" alt=""></p>
<h4 id="인터럽트-서비스-루틴">인터럽트 서비스 루틴</h4>
<p>CPU가 인터럽트 요청을 받아들이기로 했다면 CPU는 <strong>인터럽트 서비스 루틴</strong>이라는 프로그램을 실행해. </p>
<p>입출력 장치마다 인터럽트 처리하는 방법이 다르니 각각 다른 인터럽트 서비스 루틴이 필요하겠지? 그러면 CPU는 각기 다른 <strong>인터럽트 서비스 루틴을 구분</strong>할 수 있어야해. 그래서 CPU는 <strong>인터럽트 벡터</strong>를 사용해. 인터럽트 벡터는 서비스 루틴을 식별하기 위한 정보이지.</p>
<h4 id="인터럽트-서비스-루틴-중-백업">인터럽트 서비스 루틴 중 백업</h4>
<p>인터럽트를 수행하면서 이전 수행 내역을 백업해야한다고 했지. 그래서 CPU는 인터럽트 요청을 받기 전에 프로그램 카운터 값 등 <strong>현재 프로그램을 재개하기 위한 모든 내용</strong>을 <strong>스택에 백업</strong>해둬. 그리고 나서 <strong>인터럽트 서비스 루틴의 시작주소</strong>가 위치한 곳으로 프로그램 카운터 값을 갱신하고 인터럽트 서비스 루틴을 실행해.</p>
<h4 id="cpu의-인터럽트-사이클을-포함한-명령어-사이클은-이렇게-생겼어">CPU의 인터럽트 사이클을 포함한 명령어 사이클은 이렇게 생겼어</h4>
<p><img src="https://velog.velcdn.com/images/under_the_sky/post/15bd6e37-39fe-4d67-b601-7bbf1c24a072/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컴퓨터 구조] 레지스터]]></title>
            <link>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0</link>
            <guid>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-%EB%A0%88%EC%A7%80%EC%8A%A4%ED%84%B0</guid>
            <pubDate>Mon, 03 Jul 2023 15:15:15 GMT</pubDate>
            <description><![CDATA[<p>CPU안에는 ALU, 제어장치 말고도 <strong>레지스터</strong>라는 <strong>작은 임시장치</strong>가 존재해.
프로그램 속 명령어와 데이터는 <strong>실행 전후</strong>로 반드시 <strong>레지스터에 저장</strong>되지.</p>
<p>그래서 레지스터 속 값을 유심히 관찰하면 프로그램을 실행할 때 CPU내에서 무슨일이 벌어지고 있는지, 어떤 명령어가 어떻게 수행되는지 알 수 있어</p>
<h3 id="어떤-레지스터-들이-있을까">어떤 레지스터 들이 있을까?</h3>
<blockquote>
<ol>
<li>프로그램 카운터</li>
<li>명령어 레지스터</li>
<li>메모리 주소 레지스터</li>
<li>메모리 버퍼 레지스터</li>
<li>플래그 레지스터</li>
<li>범용 레지스터</li>
<li>스택 포인터</li>
<li>베이스 레지스터</li>
</ol>
</blockquote>
<h4 id="프로그램-카운터">프로그램 카운터</h4>
<p>프로그램 카운터는 <strong>메모리</strong>에서 가져올 <strong>명령어의 주소</strong>, 즉 메모리에서 읽어 들일 <strong>명령어의 주소</strong>를 저장해.</p>
<h4 id="명령어-레지스터">명령어 레지스터</h4>
<p>명령어 레지스터는 해석할 명령어, 즉 방금 메모리에서 읽어들인 명령어를 저장하는 레지스터야. 제어장치는 명령어 레지스터 속 명령어를 받아들이고 이를 해석한 뒤 제어신호를 내보내지.</p>
<h4 id="메모리-주소-레지스터">메모리 주소 레지스터</h4>
<p>메모리 주소 레지스터는 <strong>메모리의 주소</strong>를 저장하는 레지스터야. CPU가 읽어 들이고자 하는 주소값을 주소 버스로 보낼 때 메모리 주소 레지스터를 거치게 돼.</p>
<h4 id="메모리-버퍼-레지스터">메모리 버퍼 레지스터</h4>
<p>메모리 버퍼 레지스터는 <strong>메모리와 주고받을 값(데이터와 명령어)</strong>을 저장하는 레지스터야. 즉 메모리에 쓰고 싶은 값이나 메모리로부터 전달받은 값은 메모리 버퍼 레지스터를 거치게 돼. <strong>CPU가 주소 버스로 내보낼 값</strong>이 <strong>메모리 주소 레지스터</strong>를 거친다면, <strong>데이터 버스로 주고받을 값</strong>은 <strong>메모리 버퍼 레지스터</strong>를 거쳐</p>
<blockquote>
<h4 id="앞의-레지스터들-작동-방식">앞의 레지스터들 작동 방식</h4>
</blockquote>
<ol>
<li>CPU로 실행할 프로그램이 <strong>1000번지부터 1500번지까지 저장</strong>되어 있다. 1000번지에는 <strong>1101(2)가 저장</strong>되어 있다.</li>
<li>프로그램을 처음부터 실행하기 위해 PC에는 1000이 저장됨. 이는 <strong>메모리에서 가져올 명령어</strong>가 <strong>1000번지에 있다</strong>는 것을 의미한다.</li>
<li>1000번지를 읽어들이기 위해 <strong>주소 버스로 1000번지를 내보냄</strong>. 이를 위해 <strong>메모리 주소 레지스터에는 1000이 저장</strong>됨.</li>
<li><strong>&#39;메모리 읽기&#39; 제어신호</strong>와 <strong>메모리 주소 레지스터 값</strong>이 각각 <strong>제어 버스와 주소 버스</strong>를 통해 메모리로 보내짐.</li>
<li>메모리 1000번지에 저장된 값은 <strong>데이터 버스를 통해 메모리 버퍼 레지스터</strong>로 전달되고, <strong>프로그램 카운터는 증가</strong>되어 다음 명령어를 읽어 들일 준비를 함.</li>
<li>메모리 버퍼 레지스터에 저장된 값은 <strong>명령어 레지스터로 이동</strong></li>
<li>제어장치는 <strong>명령어 레지스터의 명령어를 해석</strong>하고 <strong>제어 신호를 발생</strong>시킴.</li>
</ol>
<h4 id="범용레지스터">범용레지스터</h4>
<p>범용 레지스터는 이름그대로 <strong>다양하고 일반적인 상황</strong>에서 <strong>자유롭게 사용할 수 있는 레지스터</strong>야. 메모리 버퍼 레지스터는 데이터 버스로 주고받을 값만 저장하고, 메모리 주소 레지스터는 주소 버스로 내보낼 주소값만 저장하지만, <strong>범용 레지스터는 데이터와 주소를 모두 저장할 수 있지</strong>. 일반적으로 CPU 안에는 여러개의 범용 레지스터들이 있고, 현대 대다수의 CPU는 모두 범용 레지스터를 가지고 있어.</p>
<h4 id="플래그-레지스터">플래그 레지스터</h4>
<p>플래그 레지스터는 <strong>연산결과, CPU 상태에 대한 부가적인 정보를 저장</strong>하는 레지스터야. ALU 연산 결과에 따른 플래그를 플래그 레지스터에 저장해.</p>
<h3 id="특정-레지스터를-이용한-주소-지정방식">특정 레지스터를 이용한 주소 지정방식</h3>
<p>프로그램 카운터, 스택 포인터, 베이스 레지스터는 <strong>주소 지정에 사용될 수 있는 특별한 레지스터</strong>야. <strong>스택 포인터</strong>는 <strong>스택 주소 지정 방식</strong>이라는 주소 지정 방식에 사용되고, <strong>프로그램 카운터</strong>와 <strong>베이스 레지스터</strong>는 <strong>변위 주소 지정 방식</strong>이라는 주소 지정방식에 사용돼.</p>
<h4 id="1-스택-주소-지정-방식---스택-포인터-사용">1. 스택 주소 지정 방식 -&gt; 스택 포인터 사용</h4>
<p>스택 주소 지정 방식은 <strong>스택</strong>과 <strong>스택 포인터</strong>를 이용한 주소 지정방식이야.</p>
<p>스택 포인터는 스택의 꼭대기르르 가리키는 레지스터야. 즉 스택 포인터는 스택에 마지막으로 저장한 값의 위치를 저장하는 레지스터이지</p>
<p>여기서의 스택은 <strong>자료구조의 개념적 스택</strong>과 같은 동시에 <strong>메모리 상의 있는 물리적 스택</strong>의 개념이야. 정확히는 메모리 안에 스택처럼 사용할 영역이 정해져 있는거지.</p>
<h4 id="2-변위-주소-지정-방식---베이스-레지스터-사용">2. 변위 주소 지정 방식 -&gt; 베이스 레지스터 사용</h4>
<p>명령어는 <strong>연산코드</strong>와 <strong>오퍼랜드</strong>로 이루어져 있어. 그리고 오퍼랜드 필드에는 <strong>메모리의 주소</strong>가 담길 때도 있지. <strong>변위 주소 지정 방식</strong>이란 <strong>오퍼랜드 필드의 값(변위)</strong>과 <strong>특정 레지스터의 값</strong>을 더하여 유효 주소를 얻어내는 주소 지정 방식이야.</p>
<p>이때 <strong>변위 주소 지정 방식</strong>은 오퍼랜드 필드의 주소와 어떤 레지스터를 더하는지에 따라 <strong>상대 주소 지정 방식</strong>, <strong>베이스 레지스터 주소 지정 방식</strong> 등으로 나뉘어.</p>
<blockquote>
<h5 id="상대주소-지정-방식">상대주소 지정 방식</h5>
<p>상대 주소 지정 방식은 오퍼랜드와 프로그램 카운터의 값을 더하여 유효 주소를 얻는 방식이야.</p>
</blockquote>
<blockquote>
<h5 id="베이스-레지스터-지정-방식">베이스 레지스터 지정 방식</h5>
<p>베이스 레지스터 주소 지정 방식은 오퍼랜드와 베이스 레지스터의 값을 더하여 유효 주소를 얻는 방식이야.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컴퓨터 구조] ALU와 제어장치]]></title>
            <link>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-ALU%EC%99%80-%EC%A0%9C%EC%96%B4%EC%9E%A5%EC%B9%98</link>
            <guid>https://velog.io/@under_the_sky/%EC%BB%B4%ED%93%A8%ED%84%B0-%EA%B5%AC%EC%A1%B0-ALU%EC%99%80-%EC%A0%9C%EC%96%B4%EC%9E%A5%EC%B9%98</guid>
            <pubDate>Mon, 03 Jul 2023 14:34:50 GMT</pubDate>
            <description><![CDATA[<h2 id="alu에-대해-알아보자">ALU에 대해 알아보자</h2>
<hr>
<p>ALU는 계산기 역할을 해. 컴퓨터 내부에 있는 계산기라고 볼 수 있지.
<img src="https://velog.velcdn.com/images/under_the_sky/post/96e34894-8495-4489-a6d5-78cb286b184a/image.png" alt=""></p>
<h3 id="alu는-무슨-정보를-받아들일까">ALU는 무슨 정보를 받아들일까?</h3>
<p>ALU는 계산하는 부품이야. 즉 피연산자와 수행할 연산이 필요해.
그래서 ALU는 <strong>레지스터</strong>를 통해 <strong>피연산자</strong>를 받아들이고, <strong>제어장치로</strong>부터 수행할 연산을 알려주는 <strong>제어 신호</strong>를 받아들여</p>
<h3 id="그럼-alu는-무슨-정보를-내보낼까">그럼 ALU는 무슨 정보를 내보낼까?</h3>
<p>연산 수행의 결과는 특정 숫자나 문자가 될 수 있어. 그리고 메모리 주소도 될 수 있지
이 결과값은 바로 메모리에 저장되지 않고 일시적으로 레지스터에 저장돼</p>
<blockquote>
<h3 id="왜-레지스터에-저장할까">왜 레지스터에 저장할까?</h3>
<p>그 이유는 CPU가 메모리에 접근하는 속도는 레지스터에 접근하는 속도 보다 훨씬 느리기 때문이야. 이는 CPU가 프로그램 실행속도를 늦출 수 있지</p>
</blockquote>
<p>더불어 ALU는 플래그를 내보내.
플래그에 종류에는 이러한 것들이 있어</p>
<blockquote>
<p>부호 플래그 : 연산한 결과의 부호를 나타낸다.
제로 플래그 : 연산 결과가 0인지 아닌지의 여부를 나타냄
캐리 플래그 : 연산 결과 올림수나 발림수가 발생했는지를 나타낸다.
오버플로우 플래그 : 오버플로우가 발생했는지를 나타냄.
인터럽트 플래그 : 인터럽트가 가능한지를 나타낸다.
슈퍼바이저 플래그 : 모드를 나타낸다. 커널모드인지, 사용자모드인지 구분할 수 있다.</p>
</blockquote>
<p>이러한 플래그는 CPU가 프로그램을 실행하는 도중에 반드시 기억해야하는 일종의 참고 정보야</p>
<h2 id="제어장치에-대해서-알아보자">제어장치에 대해서 알아보자</h2>
<hr>
<p>제어장치는 CPU의 구성요소 중에 하나이고 명령어를 읽어들이고 해석하는 역할을 해.
즉 제어신호를 보내고, 명령어를 해석하는 부품이지</p>
<p>제어 장치가 보낸 <strong>제어 신호</strong>는 <strong>컴퓨터 부품들을 관리</strong>하고 <strong>작동시키기 위한 일종의 전기신호</strong>이기도 해.
<img src="https://velog.velcdn.com/images/under_the_sky/post/0f219365-378a-4a04-947a-79a7113267e3/image.png" alt=""></p>
<h3 id="제어장치는-무엇을-받아들일까">제어장치는 무엇을 받아들일까?</h3>
<h4 id="1-클럭">1. 클럭</h4>
<p>제어장치는 클럭신호를 받아들여. <strong>클럭</strong>이란 컴퓨터의 모든 부품을 일사불란하게 움직일 수 있게하는 시간단위야.</p>
<p>그러나 컴퓨터부품들은 클럭이라는 박자에 맞춰 작동할 뿐이지 한 박자마다 작동하는 건 아니야</p>
<h4 id="2-해석해야-할-명령어">2. 해석해야 할 명령어</h4>
<p>제어장치는 해석해야할 명령어를 받아들여. CPU가 해석해야할 명령어는 <strong>명령어 레지스터</strong>라는 특별한 레지스터에 저장돼. 
제어장치는 이 명령어 레지스터로부터 <strong>해석할 명령어를 받아들이고 해석</strong>한 뒤, 제어 신호를 발생시켜 <strong>컴퓨터 부품들에 수행해야 할 내용</strong>을 알려줘.</p>
<h4 id="3-플래그-레지스터-속-플래그-값">3. 플래그 레지스터 속 플래그 값</h4>
<p>제어장치는 <strong>플래그 값</strong>을 받아들여 이를 참고하여 제어신호를 발생시켜. 플래그는 <strong>ALU 연산에 추가적인 상태정보</strong>야. 때문에 제어장치는 플래그 값을 받아들이고 이를 <strong>참고하여 제어 신호를 발생</strong>시키지. </p>
<h4 id="4-제어신호">4. 제어신호</h4>
<p>제어장치는 시스템 버스 중 <strong>제어 버스로 전달된 제어 신호</strong>를 받아들여
<strong>제어 신호</strong>는 CPU뿐만 아니라 입출력장치를 비롯한 <strong>CPU 외부장치도 발생</strong>시킬 수 있어. 제어장치는 <strong>제어 버스</strong>를 통해 외부로부터 전달된 <strong>제어 신호</strong>를 받아들이기도 해.</p>
<p>[출처] 혼자공부하는 컴퓨터 구조와 운영체제</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 그래프 탐색]]></title>
            <link>https://velog.io/@under_the_sky/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%89</link>
            <guid>https://velog.io/@under_the_sky/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EA%B7%B8%EB%9E%98%ED%94%84-%ED%83%90%EC%83%89</guid>
            <pubDate>Fri, 16 Jun 2023 12:24:43 GMT</pubDate>
            <description><![CDATA[<p>기본적인 그래프 탐색 방법인 깊이 우선 탐색과 너비 우선 탐색에 대해 알아보겠다.</p>
<h4 id="그래프의-모양">그래프의 모양</h4>
<pre><code>mygraph = {&quot;A&quot;: {&quot;B&quot;,&quot;C&quot;},
          &quot;B&quot;: {&quot;A&quot;,&quot;D&quot;},
          &quot;C&quot;: {&quot;A&quot;,&quot;D&quot;,&quot;E&quot;},
          &quot;D&quot;: {&quot;B&quot;,&quot;C&quot;,&quot;F&quot;},
          &quot;E&quot;: {&quot;C&quot;,&quot;G&quot;,&quot;H&quot;},
          &quot;F&quot;: {&quot;D&quot;},
          &quot;G&quot;: {&quot;E&quot;,&quot;H&quot;},
          &quot;H&quot;: {&quot;E&quot;,&quot;G&quot;}
          }</code></pre><h3 id="깊이-우선-탐색">깊이 우선 탐색</h3>
<pre><code>def dfs(graph, start, visited = set()): # 인자로 그래프, 시작 정점, 방문 정점을 받음
    if start not in visited: 
        visited.add(start) # start 정점을 방문
        print(start, end=&quot; &quot;)
        nbr = graph[start] - visited # start의 인접정점에서 방문 정점을 제외
        for v in nbr: # 방문정점을 제외한 start의 인접정점을 방문
            dfs(graph, v, visited)</code></pre><ul>
<li>스택을 사용하지 않고 순환 개념을 사용하여 깊이우선탐색을 진행</li>
<li>방문 정점을 제외한 인접정점을 방문할 때, 바로 v를 기준으로 순환함수를 실행하면서 깊은 부분을 우선적으로 탐색하는 깊이우선탐색 방식을 따름</li>
</ul>
<h3 id="너비-우선-탐색">너비 우선 탐색</h3>
<pre><code>def bfs(graph, start): # 인자로 그래프, 시작 정점을 받음
    visited = set([start]) # start 정점을 방문 정점 집합에 저장 및 집합 객체 생성
    queue = collections.deque([start]) # 큐처럼 사용할 덱 객체 생성 및 start 정점 삽입
    while queue: # 큐에 요소가 남아 있으면 계속 실행
        vertex = queue.popleft() # dequeue 실시
        print(vertex, end=&quot; &quot;) 
        nbr = graph[vertex] - visited # 인접정점에서 방문 정점 제외
        for v in nbr: # 남은 인접 정점들을 v를 큐에 삽입
            visited.add(v)
            queue.append(v)</code></pre><ul>
<li>큐를 사용하여 너비우선탐색을 진행</li>
<li>인접 정점들이 큐에 순서대로 삽입되고, 선입선출에 형태로 인접 정점들을 방문</li>
<li>시작 정점으로부터 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문하는 순회하는 너비우선방식을 따름</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 이진탐색트리 삭제]]></title>
            <link>https://velog.io/@under_the_sky/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A7%84%ED%83%90%EC%83%89%ED%8A%B8%EB%A6%AC-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@under_the_sky/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A7%84%ED%83%90%EC%83%89%ED%8A%B8%EB%A6%AC-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Fri, 16 Jun 2023 07:03:47 GMT</pubDate>
            <description><![CDATA[<p>이진 탐색트리의 삭제연산은 3가지 Case를 고려해야한다.</p>
<ol>
<li>단말 노드 삭제</li>
<li>자식이 하나인 노드 삭제</li>
<li>두개의 자식을 모두 갖는 노드의 삭제</li>
</ol>
<p>각각의 Case를 개별 함수로 정의하고 하나의 delete 함수가 필요하다.</p>
<h3 id="각-case를-전부-고려한-delete-함수">각 Case를 전부 고려한 delete 함수</h3>
<pre><code>def delete_bst(root,key):
    if root == None: return None

    parent = None
    node = root
    # 삭제할 노드를 탐색하는 과정
    while node != None and node.key != key: 
        parent = node
        if key &lt; node.key: node = node.left
        else: node = node.right

    # 삭제할 노드가 없는 경우
    if node == None: return None

    # Case1 단말 노드 삭제
    if node.left == None and node.right == None:
        root = delete_bst_case1(parent, node, root)

    # Case2 자식이 하나인 노드 삭제
    elif node.left==None or node.right ==None:
        root = delete_bst_case2(parent, node, root)

    # Case3 두개의 자식을 모두 갖는 노드의 삭제
    else:
        root = delete_bst_case3(parent, node, root)
    return root </code></pre><h4 id="case1-단말노드-삭제">Case1 단말노드 삭제</h4>
<pre><code>def delete_bst_case1(parent, node, root):
    if parent is None: # 삭제할 단말노드가 루트일 경우
        root = None # 공백트리
    else:
        if parent.left == node: # 삭제할 부모노드의 왼쪽이 삭제할 노드이면
            parent.left = None
        else:
            parent.right = None
    return root</code></pre><ul>
<li><p>삭제할 노드가 단말 노드인 경우이다. 삭제할 노드가 자기 부모의 왼쪽 노드인지 오른쪽 노드인지에 따라 삭제</p>
<h4 id="case2-자식이-하나인-노드-삭제">Case2 자식이 하나인 노드 삭제</h4>
<pre><code># case2. 자식이 하나인 노드의 삭제
def delete_bst_case2(parent, node, root):
  if node.left is not None: # 삭제할 노드가 왼쪽 자식을 가진다면
      child = node.left
  else:
      child = node.right # child는 삭제할 노드의 자식

  if node == root: # 없애려는 노드가 루트이면
      root = child # child가 새로운 루트가 됨
  else:
      if node is parent.left: #삭제할 노드가 부모의 왼쪽 자식이면
          parent.left = child # 부모의 왼쪽 자식이 child가 됨
      else:
          parent.right = child</code></pre></li>
<li><p>삭제할 노드의 자식 노드를 child라는 변수에 할당해둔다. 그리고 삭제할 노드가 자기 부모의 왼쪽노드인지 오른쪽 노드인지에 따라 child값을 삽입</p>
<h4 id="case3-두개의-자식을-모두-갖는-노드의-삭제">Case3 두개의 자식을 모두 갖는 노드의 삭제</h4>
<pre><code>def delete_bst_case3(parent, node, root):
  succp = node
  succ = node.right

  # 오른쪽 노드의 최솟값을 찾는 과정
  while(succ.left != None): # succ의 왼쪽노드가 공백이 아니면  한칸씩 내려감
      succp = succ
      succ = succ.left 

  # 다 내려왔을 때, 위로 올라갈 노드의 자식노드를 자신의 부모노드와 연결
  if(succp.left == succ): succp.left가 succ와 같다면 
      succp.left = succ.right
  else:
      succp.right = succ.right

  # 삭제할 노드에 succ 즉 후보 노드를 삽입
  node.key = succ.key
  node.value = succ.value
  node = succ

  return root</code></pre></li>
<li><p>가장 복잡한 경우이다. 삭제할 경우가 왼쪽 오른쪽 자식을 모두 가지는 경우이다. 결국에 왼쪽 노드에선 가장 큰 값, 오른쪽 노드에선 가장 작은 값을 삭제 노드에 넣어주면 된다.</p>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>