반응형

<자바 문법 및 특징>

1. 자바 특징

현실 세계의 객체를 필드와 메서드로 정의한 Class 기반으로 실제 메모리가 잡혀 만들어진 부품과 같은 객체들을 조합해

전체 프로그램을 완성해 나가는 개발 기법

  • oop : 객체 지향 언어 
  • 가비지 컬렉션에 의해 메모리 자동 관리
    • 시스템에서 더이상 사용하지 않는 동적 할당된 메모리 블럭을 찾아 자동으로 다시 사용 가능한 자원 회수하는 것
    • 시스템에서 가비지컬렉션을 수행하는 부분 : 가비지 컬렉터
  • 멀티 쓰레드 지원
  • JVM 위에서 동작하기 때문에 특정 OS에 종속적이지 않고 이식성이 좋으며 보안성이 좋다
  • 다양한 오픈 라이브러리들이 존재한
  • 추상화 :  객체의 공통적인 특징을 속성을 변수로 / 공통된 기능을 메소드로 만듬/일반메서드사용
    • 추상 메서드 : 메서드의 정의부만 있고, 구현부는 있지 않는 메서드
    • 추상 클래스 : 추상 메서드를 적어도 하나 이상 가지고 있는 클래스로 자식 클래스에서 오버라이딩(재정의)
                               필요한 추상메서드를 가지고 있기 때문에 객체화 할 수 없다.
  • 캡슐화 , 은닉화 : 외부 객체에서 구현 방식 알 수 없도록 숨기고 별도로 접근할 수 있는 getter/setter 메서드를 통해 접근하는 방식
  • 상속 : 부모 class를 자식이 접근할 수 있도록 물려 받는 방식
    • 변수와 메소드를 그대로 쓰므로 코드 중복을 줄이고
    • 객체 사용하는 클래스의 외부 관점으로 봤을 때, 묶어서 처리(upcasting)할 수 있으므로 효율적인 코드
  • 다형성 : 부모 class 타입으로 해당 부모를 상속받는 여러 자식 class를 대입하는 성질 
                  : 서로 다른 class로 부터 만들어진 객체이지만 같은 부모 class 타입으로 대입할 수 있는 성질
    • 오버로딩
      • 하나의 클래스 내에 이름이 같은 여러 개의 메서드 정의
      • parameter, return 타입 등이 다른데, 수행 내용이 본질적으로 동일 할 때 사용
    • 오버라이딩
      • 부모 클래스의 메소드를 자식 클래스에서 재정의

2. 객체와 클래스의 차이점

  • 클래스 : 현실 세계의 객체 속성과 동작을 추려내 필드와 메서드로 정의한 것 "아직 메모리가 할당되지 않은 상태"
  • 객체 : 클래스라는 설계도를 기반으로 실제 메모리가 잡힌 것을 의미,
                이런 객체를 조합해 전체 프로그램을 완성해나가는 방식 OOP

3. Servlet , JSP

  • Servlet : Container 가 이해할 수 있게 구성된 순수 자바 코드로만 이루어진 것(html in java)
  • jsp : html 기반에 java코드를 블록화하여 삽입 (java in html)

4. GET, POST

  • GET : 웹 브라우저가 웹 서버에 데이터를 요청할 때 사용 
    • 보안성이 떨어지고 , 길이 제한이 있다
    • POST 보다 상대적으로 전송 속도가 post보다 빠름
    • 웹 브라우저에서 웹 서버로 전달되는 데이터가 인코딩 되어 URL에 붙는다
  • POST : 웹 브라우저가 웹 서버에 데이터를 전달하기 위해 사용
    • HTTP 메시지로 넘어온 엔티티를 새로운 자원으로 등록 : 201 response
    • 보안성이 높고, 속도가 get 보다 느리다
    • 객체들의 값도 전송 가능 
    • PUT(식별자 포함하여 웹 서버에 데이터를 전달)과는 비슷하게 작동

5. Call by reference , Call by value

  • Call by reference : 매개 변수가 원래 주소에 값을 저장
  • Call by value : 주어진 값을 복사하여 처리 

6. interface?

모든 메서드가 구현부가 없는 추상메서드, abstract 키워드 붙이지 않아도 자동으로 모든 메서드는 추상 메서드로 정의

  • 인터페이스는 추상화와 다르게 메서드 선언만 가능
  • 변수도 자동으로 final static 키워드가 붙는다. 

7. 접근제한자

  • public(접근 제한자가 없다/ 같은 프로젝트 내 어디서든 사용 가능 )
  • protected(같은 패키지 내, 다른 패키지에서 상속받아 자손 클래스에서 접근)
  • default (같은 패키지 내에서만 접근 가능)
  • private (같은 클래스내에서만 접근 가능)

8. 소켓 통신 (tcp/udp)

  • tcp (transmission control protocol)
    • 연결형 서비스 제공
    • 높은 신뢰성 보장
    • 데이터 흐름 , 호잡 제어
    • 3,4 -way handshaking(데이터 수신 여부 확인)
    • 전이중, 점대점 서비스
  • udp (user datagram protocol)
    • 비연결형 서비스 제공
    • 신뢰성 낮음
    • 데이터 전송 순서 바뀜
    • 데이터 수신 여부 확인 과정 없음
    • tcp 보다 전송 속도가 빠름

9. Primitive type , Reference type

  • Primitive type : 변수에 값 자체 저장
    • 정수 / 실수 / 문자 / 논리형
    • wrapper class (간단한 데이터를 객체로 만들어야 할 경우)를
      통해 객체로 변형 가능 (int, char 제외하고 다른 자료형들은 맨 앞 알파벳을 대문자로 바꿔준다)
  • Reference type : 메모리상에 객체가 있는 위치 저장
    • class , interface , array

10. 세션, 쿠키 사용 

  • Session : 웹 브라우저의 캐시에 저장(서버에 저장)되어 브라우저가 닫히거나 서버에 삭제 시 사라진다
                      쿠키에 비해 보안성이 좋다
  • Cookie : http 한계를 극복 / 인터넷 웹 사이트의 방문 기록을 남겨 사용자와 웹 사이트를 매개 
                               아이디 , 비밀번호 / Client PC에 저장, 다른 사용자에 의해 임의 변경 가능 
  • 쿠키 대신 세션 사용하면 되는데 안하는 이유?
     -> 세션에 저장하면 서버의 메모리가 과도하게 사용되어 서버에 무리가 감

11. 해쉬, 암호화

  • 해쉬 : 단방향 암호화 / 복호화 불가능 / 데이터 보안에 중점
  • 암호화 : 양방향 암호화 / 복호화 가능 / 통신 보안 중점
    • Symmetric key (비밀키 : des / aes) / Asymmetric key(공개키 : dsa , rsa) 

12. HTTP (Hyper Text Transfer Protocol)

  • 웹브라우저와 웹서버가 서로 데이터를 주고 받을 때, 사용하는 규약
  • 도메인 + URL(자원 위치) , 도메인 + URI(자원 식별자) 통해 요청, 서버가 요청에 따른 응답(.html) 해줌
  • 특징
    • Connectless + stateless : 클라이언트 이전 상태 알 수 없으므로(쿠키와 세션 필요)
    • keep-alive : 지정된 시간 동안 연결 끊지 않고 연결된 상태 유지
      웹 서버 연결 -> html 문서 다운로드 -> 필요한 img , js, css 다운 -> 연결 끊음
  • http method 
    • GET : 정보를 요청하기 위해 사용 (READ)
    • POST : 정보를 입력하기 위해 사용(CREATE)
    • PUT : 정보를 업데이트 하기 위해 사용 (UPDATE)
    • DELETE : 정보를 삭제하기 위해 사용 (DELETE)
  • Request Header : 웹 브라우저가 웹 서버에 요청할 때 작성
    • 유저가 서버 측에 요청한 정보
  • Response Header : 웹 서버가 작성해서 웹 브라우저에 응답할 때 작성
    • 유저의 요청(request)에 서버 측의 응답(response)정보
  • https : http는 데이터 key와 , value 가 모두 표시되기 때문에 중요한 데이터 일 때 감춰야 함(HTTPS) 

13. REST API 

  • 서버에 리퀘스트 할 때, 자원의 ID와 자원에 대한 처리(HTTP 메소드)를 포함하여 리퀘스트 되도록 하는 것
  • 고유 자원에 대한 처리 URI로 나타낸 것
  • 라우터 상에서 HTTP 메소드 (GET, POST, PUT, DELEE) 와 실제 자원에 대한 처리 (CRUD)를 맵핑 시켜야함
  • HTTP method + 모든 개체 리소스화
    + URL 디자인(라우팅 :
    클라이언트 요청에 대한 응답을 어떻게 이어줄 것인가 처리 / 자원에 대한 처리를 주소에 나타내지 않는다. )

14. 아파치, 아파치 톰캣

  • 아파치 : HTTP 웹 서버(클라이언트의 요청을 기다리고 요청에 대한 데이터(정적 데이터)를 만들어서 응답하는 역할)
  • 톰캣 : WAS(Web Application Server/ 서블릿 컨테이너) : 웹 서버와 웹 컨테이너 결합
    • 다양한 기능을 컨테이너에 구현하여 다양한 역할을 수행
    • 웹 컨테이너 : 클라이언트의 요청이 있을 때, 내부 프로그램을 통해 결과를 만들어내고 이것을 다시 클라이언트에게 돌려줌
      • JSP, 서블릿 처리 / 서블릿 수명 주기 관리 / 요청 URL을 서블릿 코드로 매핑 / HTTP 요청 수신 및 응답 / 필터 체인
  • 둘의 차이 : 웹 서버와 웹 어플리케이션 차이-> 단순 정적 데이터 (이미지나 단순 HTML)를 처리하는 서버라면 아파치 
    -> 동적 데이터 (DB 연결, 데이터 조작) 등 과 같은 처리 는 WAS

15. 동기, 비동기 

  • 동기 (synchronous) 
    • 요청과 그 결과가 한 자리에서 동시에 일어남
    • A노드와 B 노드 사이의 작업 처리 단위(transcation)을 동시에 맞추겠다
    • 장점 : 설계가 매우 간단, 직관적 / 단점 : 결과가 주어질 때 까지 아무것도 못하고 대기해야한다.
  • 비동기 (asynchronous)
    • 요청한 그 자리에서 결과가 주어지지 않음
    • 노드 사이의 작업 처리 단위를 동시에 맞추지 않아도 된다.
    • 장점 : 결과가 주어지는 데 시간이 걸리더라도 그 시간 동안 다른 작업할 수 있으므로 자원을 효율적으로 사용
      단점 : 동기보다 복잡

16. 쓰레드 , 프로세스

  • Process : 운영체제에서 실행 중인 하나의 프로그램(하나 이상의 쓰레드 포함)
  • Thread : 프로세스 내에서 동시에 실행되는 독립적인 실행 단위 (stack메모리)
    • 장점 
      • 빠른 프로세스 생성
      • 적은 메모리 사용
      • 쉬운 정보 공유
    • 단점
      • 교착상태(다중 프로그래밍 체제에서 하나 , 그 이상의 프로세스가 수행 할 수 없는 어떤 특정 시간 /
                           하나의 메서드를 여러 개의 쓰레드가 한번에 사용하게 되면 데드락 발생)
  • Thread 와 Process 차이
    • 이 프로세스 내에서 실행되는 각각의 일을 스레드 
    • 프로세스 내에서 실행되는 세부 작업 단위로 여러 개의 스레드가 하나의 프로세스를 이루게 됨
    • 자바에서 main()메서드를 수행하기 위한 목적으로 제공된다 하여 main 쓰레드라 불린다 
    • 서로 메모리 공간을 공유하지 못해, IPC(Inter process communication) 방식이 필요

17.자바의 메모리 영역(간단하게 설명)

  • 메서드 영역 : static 변수, 전역변수, 코드에서 사용되는 Class 정보 등.
    • 코드에서 사용되는 class들을 로더로 읽어 클래스별로 런타임 필드데이터, 메서드 데이터 등을 분류해 저장
  • 스택(Stack) : 지역변수, 함수(메서드) 등이 할당되는 LIFO(Last In First Out) 방식의 메모리
  • 힙(Heap) : new 연산자를 통한 동작할당된 객체들이 저장되며, 가비지 컬렉션에 의해 메모리가 관리

 

18. 컬렉션 프레임워크 

다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화 된 방법을 제공하는 클래스 집합

즉, 데이터를 저장하는 자료 구조, 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현

인터페이스를 사용해 구현

  • List 인터페이스
    • 순서가 있는 데이터 집합, 데이터 중복 허용
    • vector , arraylist , linkedlist , stack , queue
  • Set 인터페이스
    • 순서가 없는 데이터 집합, 데이터 중복 허용 x
    • hashSet, TreeSet
  • Map 인터페이스
    • 키와 값의 한 쌍으로 이루어지는 데이터 집합, 순서가 없음
    • 키는 중복 허용 x, 값은 중복 가능
    • haspmap , treemap, hashtable, properties

19. 제네릭

코드 블럭 내부에서 쓸 자료형을 외부에서 지정하는 기법

하지 않으면, 원하지 않는 자료형이 입력되었을 때 오류를 컴파일 시점에 잡아낼 수 없다

클래스<사용할 타입>

 

20. 자바 재귀함수

자기 자신을 호출하는 함수 

원래 범위의 문제에서 더 작은 범위의 하위 문제를 먼저 해결함으로 원래 문제 해결 

꼭 재귀호출이 끝나는 종료 조건이 있어야 한다

 

반응형
반응형

1. 데이터베이스 백업

- 백업을 위한 명령어  : mongodump

• dumps the entire data of your server into the dump directory

   (서버의 전체 데이터를 덤프 디렉토리에 덤프)

• 백업 단위 선택 가능 : 컬렉션/데이터베이스/전체 데이터베이스 단위

 

ex) mongod 서버가 로컬호스트(포트# : 27017)에서 동작 중인 경우

• mongodb가 설치된 bin 폴더로 이동 후 mongodump 명령 입력

• 모든 데이터를 BSON 파일 형식으로 /bin/dump 폴더에 백업 수행

 

- mongodump와 함께 쓰는 옵션

 

Syntax Description Example
mongodump --host HOST_NAME --port PORT_NUMBER

This commmand will backup all databases of specified mongod instance.

(지정된 mongod 인스턴스의 모든 데이터베이스를 백업)

mongodump --host tutorialspoint.com --port 27017
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY

This command will backup only specified database at specified path.

( 지정된 경로에서 지정된 데이터베이스 만 백업)

mongodump --dbpath /data/db/ --out /data/backup/
mongodump --collection COLLECTION --db DB_NAME

This command will backup only specified collection of specified database.

(지정된 데이터베이스 모음만 백업)

mongodump --collection mycol --db test

 

2. 백업된 데이터 복원(restore)  명령 : mongorestore

• restores all of the data from the backup directory

 

##mongodump and mongostore are not ideal for capturing backups of larger systems.

(위 두 명령어는 큰 시스템의 백업 캡쳐에 적합하지 않다)

 

3. Relationship

• represents how various documents are logically related to each other

(다양한 문서가 서로 논리적으로 어떻게 연관되어 있는지 나타낸다)

• can be either 1:1, 1:N, N:1 or N:N

• can ne modeled via Embedded and Referenced approaches.

(embedded 및 referenced 접근 방식을 통해 모델링)

 

ex) 사용자의 주소 저장하는 경우 (여러 개의 주소 가능 -> 1:N 관계 성립)

{ "_id":ObjectId("52ffc33cd85242f436000001"),
"name": "Tom Hanks",
"contact": "987654321",
"dob": "01-01-1991" } //USER
{"_id":ObjectId("52ffc4a5d85242602e000000"),
"building": "22 A, Indiana Apt",
"pincode": 123456, "city": "Los Angeles",
"state": "California" } //Address

1) Embedded Relationships = denormalized relationship 

• maintains all the related data in a single document, which makes it easy to retrieve and maintain

(모든 관련 데이터를 단일 문서로 유지 관리하여 쉽게 사용할 수 있도록 한다(회수 하여 유지))

 

{
"_id":ObjectId("u001"),
"name": "Tom Hanks", . . .
"address": [ { "building": "22 A, Indiana Apt", . . . },
                        { "building": "170 A, Acropolis Apt", . . . } ] }
                      ]
}

whole document can be retrieved in a single query

(전체 문서는 단일 쿼리로 검색할 수 있다)

db.users.findOne({"name":"Tom Hanks"},{"address":1})

• drawback(단점)

– if the embedded document keeps on growing too much in size, it can impact the read/write performance.

(포함된 문서의 크기가 계속 커지면 읽기 / 쓰기 성능에 영향을 미칠 수 있다)

 

 2) Referenced Relationships (참조 관계)= normalized relationship(정상화 관계)

• both the user and address documents will be maintained separately but the user document will contain a field that will reference the address document's id field.

(사용자 문서와 주소 문서는 별도로 유지되지만, 사용자 문서에는 주소 문서의 ID 필드를 참조하는 필드가 포함)

{
"_id":ObjectId("u001"),
. . .
"name": "Tom Hanks",
"address_ids": [ ObjectId("a001"), ObjectId("a002") ]
}

• need two queries: first to fetch the address_ids fields from user document and second to fetch these addresses from address collection.

(두 가지 쿼리가 필요 / 첫째는 사용자 문서에서 address_ids 필드를 가져오는 것 => 둘 째는 주소 집합에서 이 주소를 가져오는 것)

> var result = db.users.findOne({"name":"Tom Hanks"}, {"address_ids":1})
> db.address.find({"_id":{"$in":result["address_ids"] }})
//result 문서에서 address_ids 필드의 값만 추출 [ObjectId("a001"), ObjectId("a002")]

4. Database References

1)  For many use cases in MongoDB(몽고디비의 많은 사용 사례)

      • the denormalized data model where related data is stored within a single document will be optimal (embedded reltaionship)(관련 데이터가 저장되는 공식화된 데이터 모델 : 단일 문서가 최적 / 임베디드 Relationship)

      • in some cases, it makes sense to store related information in separate documents, typically in different collections or databases (normalized relationship)

            (경우에 따라 관련 정보를 별도로 저장하는 것이 타당 / 일반적으로 서로 다른 컬렉션 또는 DB 에 있는 문서(정규화된 관계))

 

2) two methods for relating documents in mongoDB applications(몽고디비 응용프로그램에서 Document와 관련된 2가지)

      • Manual references(수동 참조)

         – you save the _id field of one document in another document as a reference.
            Then your  application can run a second query to return the related data.

            (하나의 document에 id 필드를 저장하고 다른 document에서 참조하면 된다 
               / 응용프로그램에서 두 번째 쿼리를 실행하여 반환할 수 있다)

         – simple and sufficient method for most use cases.

             (대부분의 사용 사례에 대한 간단하고 충분한 방법)

      • DBRefs

      – references from one document to another using the value of the first document‟s _id field, collection name, and,             optionally, its database name

        (dbrefs를 사용하여 한 문서에서 다른 문서로 참조 /  _id 필드, 컬렉션 이름 및 데이터베이스 이름(선택 사항) 등이 있다)

      – in cases where a document contains references from different collections, we can use this method

         (document에 다른 collection이 포함되어 있다면 , 위의 방법을 사용한다)

 

3) Using DBRefs

• $ref 필드 : 참조되는 문서가 속한 컬렉션 이름↓

• $id 필드 : 참조되는 문서의 _id 필드

• $db 필드 : 참조되는 문서가 속한 데이터베이스 이름 (옵션)

아래 방향으로 필드 순서 주의 해서 사용해야한다.

 

{
"_id":ObjectId("53402597d852426020000002"),
"address": {
          "$ref": "address_home",
          "$id": ObjectId("534009e4d852427820000002"),
          "$db": "tutorialspoint"},
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Hanks" 
}
> var user = db.users.findOne({"name":"Tom Hanks"})
> var dbRef = user.address
> db[dbRef.$ref].findOne({"_id":(dbRef.$id)})

 

 

5. Covered Queries

1) covered query

• 인덱스만 이용해서도 처리가 가능한 질의 (데이터베이스 접근 없음)

• a query that can be satisfied entirely using an index and does not have to examine any documents

(인덱스를 사용하여 완전히 만족할 수 있고, 그 어떤 document도 검토할 필요가 없는 질의)

• 질의 처리에 필요한 모든 데이터가 인덱스에 있을 때 „이 인덱스가 해당 질의를 커버 한다‟라고 함

• An index covers a query when all of the following apply:(모두 적용되면 index는 query를 다룬다)

       – all the fields in the query are part of an index, and(쿼리의 모든 필드는 index의 일부분)

       – all the fields returned in the results are in the same index(결과에 반환되는 모든 필드가 동일한 index에 있음)

       – no fields in the query are equal to null(쿼리에 null과 동일한 필드가 없음)

 

{
"_id": ObjectId("53402597d852426020000002"),
"contact": "987654321",
"dob": "01-01-1991",
"gender": "M",
"name": "Tom Benzamin",
"user_name": "tombenzamin"
}

First. create a compound index for the users collection on the fields gender and user_name using the following query 

>db.users.ensureIndex({gender:1,user_name:1})

this index will cover the following query

>db.users.find({gender:"M"},{user_name:1,_id:0}) //ID필드는 결과 문서에서 반드시 제외시켜야 함

 

 

6. Analyzing Queries

-  Analyzing queries is a very important aspect of measuring how effective the database and indexing design is.

(쿼리 분석하는 것은 효과적으로 데이터베이스와 인덱스를 디자인하는데 있어 매우 중요한 측면)

1) $explain( ) 연산자

    • provides information on the query, indexes used in a query and other statistics

    (쿼리에 대한 정보, 쿼리에 사용된 인덱스 및 기타 통계 제공)

    • very useful when analyzing how well your indexes are optimized

    (인덱스가 얼마나 최적화 되어있는지 분석할 때 유용)

    • 사용 예)

> db.users.find({gender:"M"},{name:1, _id:0}).explain()
결과 
>{ "cursor" : "BtreeCursor gender_1_user_name_1", "isMultiKey" : false, "n" : 1, "nscannedObjects" : 0, "nscanned" : 1, "nscannedObjectsAllPlans" : 0, "nscannedAllPlans" : 1, "scanAndOrder" : false, "indexOnly" : true, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "gender" : [ [ "M", "M" ] ], "user_name" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] } }

2) $hint( ) 연산자

    • forces the query optimizer to use the specified index to run a query

       (쿼리 최적화가 지정된 인덱스를 사용하여 쿼리를 실행하도록 강제 적용)

    • particularly useful when you want to test performance of a query with different indexes

       (다른 인덱스로 쿼리 성능을 테스트하는데 유용)

    • 사용 예)

>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

 

7. Atomic Operations

1) MongoDB provides atomic operations on only a single document

(몽고디비는 단일 document)에서만 atomic operations 을 제공

2) The recommended approach to maintain atomicity(원자성 유지하기 위한 권장하는 접근법)

    • keep all the related information, which is frequently updated together in a single document using embedded     documents(임베디드 문서를 사용하여 단일 문서로 자주 업데이트 되는 모든 관련 정보를 보관)

 =>  all the updates for a single document are atomic.(단일 document 에 대한 모든 업데이트는 원자적)

     • findAndModify 명령의 활용 예)

{ "_id":1,
             "product_name": "Samsung S3",
             "product_available": 3,
             "product_bought_by": [{ "customer": "john", "date": "7-Jan-2014"}, { "customer": "mark", "date": "8-Jan-2014"} ] }
> db.products.findAndModify({
            query:{_id:2,product_available:{$gt:0}},
            update:{ $inc:{product_available:-1},
                             $push:{product_bought_by:{customer:"rob",date:"9-Jan-2014"}} }
})

8. Advanced Indexing

{
"address": {
            "city": "Los Angeles",
            
"state": "California",
             "pincode": "123"
            
},
"tags": [
            
"music",
            
"cricket",
            
"blogs"
            
],
"name": "Tom Benzamin"
}

1) 배열을 필드 값으로 가지는 인덱싱 : multikey index 로 구성

multikey index 

– 배열의 각 요소 마다 인덱스 엔트리 유지

    =>  같은 배열에서 생성된 여러 엔트리들은 동일한 문서를 참조(포인트)

  user tag를 기반으로 user document를 검색한다 가정 / collection의 tag 배열에 index를 생성

 배열에 index 작성 시 , 각 필드에 대한 별도 index 항목이 작성 

==> 태그 배열에서 index 생성 시, music/ cricket / blogs 값에 대해 별도의 index 생성

 

> db.users.createIndex({"tags":1})
//태그 배열에 index 생성 
> db.users.find({"tags":"cricket"})
//index 생성 후 컬렉션의 태그 필드 검색 
> db.users.find({"tags":"cricket"}).explain()
//적절하게 사용되었는지 확인하려면 explain 명령 사용

"cursor": "BtreeCursor tags_1"//결과

 

2) 서브 문서를 필드 값으로 갖는 인덱싱

– 서브 문서의 모든 필드들에 대한 인덱스 생성 =>  compound index로 구성

도시 , 주 및 핀코드 필드 기반 문서 검색 / 

   => 모든 필드는 주소, 하위 문서 필드의 일부 이므로 -> 하위 문서의 모든 필드에 대한 index 생성

db.users.createIndex({"addr.city":1},{"addr.state":1}, {"addr.pincode":1})
//하위 문서의 세 필드 모두에 대한 index 
db.users.find({"addr.city":"LA"})
//index을 사용하는 하위 문서 필드 검색 가능 
db.users.find({"addr.city":"LA", "addr.state":1})
//쿼리 식은 지정된 index 순서를 따라야함 
db.users.find({"addr.city":"LA", "addr.state":1, "addr.pincode":1})

 

반응형
반응형

1. 데이터베이스 파티셔닝 (Database partitioning)

  • 데이터베이스를 분리하여 여러 서버에 분산, 저장 및 관리하는 기술
  • 파티셔닝 유형 (2가지)
    • 수직 파티셔닝 (vertical) 
      • 하나의 테이블의 컬럼들을 여러 테이블로 분리하는 방법
      • ex) R(A1, A2, A3, A4, A5)  == > R1(A1, A2, A3, A4) / R2(A1, A5)
    • 수평 파티셔닝(=샤딩)(horizontal)
      • 로우 (문서) 별로 데이터베이스를 분할하는 방법
      • 샤드(shard) : 분할된 각 데이터 조각 의미. 둘 이상의 서버에 분산 저장

2. Sharding in mongoDB(목적 : 데이터 분산 저장(부하 분산) / 백업, 복구 전략(안정적) / 빠른 처리 성능)

- 시스템이 더 이상 부하를 견디지 못할 때, Sharding 을 통해 가용성을 늘려주고, 버틸 수 있는 throughput도 늘려준다

- a method for distributing data across multiple machines by horizontal scaling to meet the demands of data growth

- adds more machines (scale out ) to support data growth and the demands of read and write operations

- for storage and load distribution

 

 

- 왜 샤딩을 사용하나?

  • In replication, all writes go to master node
  • Latency sensitive queries still go to master
  • Single replica set has limitation of 12 nodes
  • Memory can't be large enough when active dataset is big
  • Local disk is not big enough
  • Vertical scaling is too expensive

 

 

  • shard: Each shard contains a subset of the sharded data. Each shard can be deployed as a replica set.
    • 각 샤드에는 샤드 데이터의 하위 집합이 포함 / 각 샤드는 replica set로 배치한다.(고가용성 위해)
    • sharded cluster 안에서 sharded data의 subset을 가진다 
    • clusert의 shard 들에 존재하는 데이터를 합하면 원본의 데이터가 된다. 
    • 하나의 shard에 대해 query를 실행하면 , 해당 shard 안의 데이터에 대해서만 결과를 가져온다 / cluster level에서 query를 실행하고 싶다면, mongos 사용
    • 하나의 데이터베이스 안에 primary shard(shard 되지 않은 모든 collection 저장) 는 반드시 존재
  • mongos(=routers): cache the cluster metadata and act as a query router, providing an interface between client applications and the sharded cluster.
    • 클러스터 메타데이터를 캐시화하고, 클라이언트 어플리케이션과 Sharded 클러스터간의 인터페이스를 쿼리라우터 역할로서 제공한다.
    • 적절한 shard 로 route 하기 위해 config server로부터 metadata를 캐싱 
    • 각각의 shrad에 대해 query 를 분산시키기 위해 mongos라는 instance를 제공 
    • 어떠한 data나 설정 정보를 저장하지 않는다.
    • mongos 서버를 통해 데이터를 읽고, 쓰고 / config 서버의 metadata를 캐시 / 빅데이터를 샤드 서버로 분산하는 프로세스
  • config servers: store metadata persistently and configuration settings for the cluster
    • 클러스터에 대한 메타데이터 및 구성 설정을 영구 저장
    • 모든 shard에 대해 어떤 chunk를 들고 있는지 정보를 가지고 있고, 해당 metadata를 mongos에서 활용하여 query를 route한다.
    • 클러스터 설정 저장하는 server
    • config server로부터 data를 동기화 한다 
    • 샤드 서버의 인덱스 찾는데 필요/ 샤드 시스템에 대한 메타 데이터 저장 , 관리 역할
  • 샤드 키 (shard keys)
    • used to distribute the collection‟s documents across shards
    • 클러스터들의 샤드들 간에 collection의 document를 어떻게 분산할 것인가 결정
    • consists of a field or fields that exist in every document in the target collection
    • 대상 집합의 모든 document에 존재하는 필드로 구성
    • 컬렉션을 샤딩할 때, 샤드 키 선택 / 샤딩 후에는 변경 불가 
    • 여러 개의 shard 서버로 분할된 기준 필드 가르킴
    • partition 과 load balancing 의 기준, mongodb 데이터 저장과 성능에 절대적인 영향
  • 청크(chunks)
    • a contiguous range of shard key values within a particular shard 
    • 특졍 샤드 내의 연속적인 샤드 키 값 범위
    • each chunk has an inclusive lower and exclusive upper range based on the shard key. 
    • 각 청크에는 샤드 키를 기반으로 하는 포괄적인 하한 범위와 배타적인 상위 범위가 존재한다.
    • default size : 64 MB
    • 일정한 데이터양에 도달했을 때, 서버로 분할하는 단위
  • balancer and even chunk distribution
    • to achieve an even distribution of chunks across all shards in the cluster, a balancer runs in the background to migrate chunks across the shards when a shard contains too many chunks of a collection relative to other shards
    • 클러스터의 모든 파편에 걸쳐 고르게 분포하기 위해 , 샤드에 다른 파편에 비해 너무 많은 컬렉션 덩어리가 포함되어 있을 때, 밸런서가 백그라운드에서 실행되어 파편에 걸쳐 청크를 마이그레이션(데이터의 이동, 서버에 균등하게 데이터를 재조정하는 과정) 한다.

3. Sharding 의 이점

읽기 및 쓰기 (Reads / Writes)

           – read and write workloads can be scaled horizontally across the shards in the cluster by adding more shards.

           – for queries that include the shard key or the prefix of a compound shard key, mongos can target the query at a                     specific shard or set of shards

          – 샤드 클러스터의 샤드에 읽기 및 쓰기 워크로드를 분산시켜 각 샤드가 클러스터 작업의 서브 세트를 처리할 수 있도록

          –  더 많은 샤드를 추가하여 읽기 쓰기 워크로드를 클러스터 전체에 수평적으로 확장 할 수 있게.

• 저장 용량 (Storage Capacity)

          – each shard contains a subset of the total cluster data

          – as the data set grows, additional shards increase the storage capacity of the cluster.

          – 클러스터의 샤드에 데이터를 분산시켜 각 샤드가 전체 클러스터 데이터의 서브 세트를 포함.

          – 데이터 세트가 커짐에 따라 , 추가 샤드가 클러스터의 스토리지 용량을 증가 

고가용성 (High Availability)

           – a sharded cluster can continue to perform partial read / write operations even if one or more shards are                               unavailable 

          – in production

         – 클러스터는 한 개 이상의 shard를 사용할 수 없는 경우에도 부분 읽기 / 쓰기 작업을 계속 수행할 수 있음.

 

» 각 shard는 복제 세트로 구성 » config server는 최소 3개의 노드들로 구성된 복제 세트로 구성

 

4. Sharded and Non-Sharded Collections(샤드 및 비샤드 컬렉션)

• A database can have a mixture of sharded and unsharded collections

   - 데이터베이스에 샤드와 비샤드 컬렉션이 혼합되어 있을 수 있음

• Sharded collections are partitioned and distributed across the shards in the cluster. Unsharded collections are stored on a primary shard

   - 샤드 컬렉션이 샤드 컬렉션 안에서 분할과 분포되어있으면, 비샤드 컬렉션이 primary 샤드에 저장된다. 

샤드 및 비샤드 컬렉션

5. Connecting to a Sharded Cluster(샤드 클러스트에 연결)

     • you must connect to a mongos router to interact with any collection in the sharded cluster

     - 샤드 클러스터의 컬렉션과 상호작용하려면 mongos 라우터에 연결해야한다.

     • you can connect to a mongos via the mongo shell or a MongoDB driver

     - mongos를 사용하여 몽고쉘이나 몽고드라이버와 연결. 

mongos를 사용하여 샤드클러스터에 연결

6.  Two Sharding Strategies for distributing data across sharded clusters(샤드 클러스트에 데이터 배포하는 두가지 샤드 전략)

   1) Ranged sharding(범위 샤딩)

     • dividing data into several ranges based on the shard key values(샤드 키 값을 기준으로 데이터를 여러 범위로 구분)

     • Each chunk is then assigned a range based on the shard key values (각 청크에는 샤드 키 기초한 범위가 할당)

     • A range of shard keys whose values are “close” are more likely to reside on the same chunk 

        (값이 닫힘인 다양한 샤드 키가 동일한 청크에 더 많이 상주할 수 있음)

     • The efficiency of ranged sharding depends on the shard key chosen(선택한 샤드키에 따라 범위 내 샤딩 효율성이 달라짐)

Ranged sharding

   2)Hashed Sharding(해시 샤딩)

     • computing a hash of the shard key field‟s value(샤드 키 필드 값의 해시 계산)

     • Each chunk is then assigned a range based on the hashed shard key values.
       (각 청크에는 해시된 샤드 키 값에 기초한 범위가 할당)

     • While a range of shard keys may be “close”, their hashed values are unlikely to be on the same chunk.

        Data distribution based on hashed values facilitates more even data distribution, especially in data sets where

        the shard key changes monotonically

         (다양한 샤드 키가 닫힘 일 수 있지만, 해시된 값은 동일한 청크 위에 있지 않는다 / 해시된 값에 기반한 데이터 배포를 통해 특히,

          샤드 키가 단조롭게 변경되는 데이터 세트에서의 데이터 배포를 더욱 원활하게 수행)

Hashed Sharding

7. setting up a local test

      -> router(mongos) 1 + config server(mongod/ replica set 구성 필수) 1 + shard(mongod / replica set 구성 필수) 2

 

setting up a local test

[1단계] 6개 노드에 대한 데이터 폴더 생성

• c:\data\configdb1 와 c:\data\configdb2

• c:\data\shard1a 와 c:\data\shard1b

• c:\data\shard2a 와 c:\data\shard2b 

 

[2단계] config server 실행 및 복제 세트 구성

#1 ->  c:\> mongod -–configsvr -–port 27500 -–dbpath c:\data\configdb1 --replSet crs
#2 ->  c:\> mongod -–configsvr -–port 27501 -–dbpath c:\data\configdb2 --replSet crs 
#3 ->  c:\> mongo -–port 27500 
           > conf = {_id:”crs”, members:[{_id:0, host:”localhost:27500”},
           {_id:1, host:”localhost:27501”}]}
             > rs.initiate(conf) // 복제 세트 초기화
             . . . .
           crs:SECONDARY>
           crs:PRIMARY>

 

[3단계] router(mongos) 실행

#4  -> c:\> mongos -–port 27100 –-configdb crs/localhost:27500 

[4단계] shard #1 인스턴스 실행 및 복제 세트 구성

#5 ->  c:\> mongod -–shardsvr -–port 27200 -–dbpath c:\data\shard1a --replSet srs1 
#6  -> c:\> mongod -–shardsvr -–port 27201 -–dbpath c:\data\shard1b --replSet srs1
#7 ->  c:\> mongo -–port 27200  
           > conf = {_id:”srs1”, members:[{_id:0, host:”localhost:27200”},
           {_id:1, host:”localhost:27201”}]}
             > rs.initiate(conf) // 복제 세트 초기화 
             . . . . 
          srs1:SECONDARY> 
          srs1:PRIMARY>

[5단계] shard #2 인스턴스 실행 및 복제 세트 구성

#8 ->  c:\> mongod -–shardsvr -–port 27300 -–dbpath c:\data\shard1a --replSet srs2
#9  -> c:\> mongod -–shardsvr -–port 27301 -–dbpath c:\data\shard1b --replSet srs2
#10 ->  c:\> mongo -–port 27300  
           > conf = {_id:”srs2”, members:[{_id:0, host:”localhost:27300”},
           {_id:1, host:”localhost:27301”}]}
             > rs.initiate(conf) // 복제 세트 초기화 
             . . . . 
          srs2:SECONDARY> 
          srs2:PRIMARY>

 

[6단계] shard #1과 shard #2를 shard cluster에 추가

• mongos에 연결 후 runCommand 명령으로 shard #1 & #2를 추가

• shard 추가 및 데이터 sharding은 db가 admin일 때만 가능

#11 -> c:\> mongo –-host localhost -–port 27100 . . .
mongos> use admin
mongos> db.runCommand({addShard:”srs1/localhost:27200, localhost:27201”, allowLocal:true})
mongos>
mongos> db.runCommand({addShard:”srs2/localhost:27300, localhost:27301”, allowLocal:true})
mongos>
mongos> sh.status()

[7단계] sharding 할 데이터 생성

#11 ->  mongos>
mongos> use myshdb2
mongos> db.mycol.insert({“name”:“kim”, “year”:“1”})
mongos> . . . // 추가 삽입 n회
mongos> db.mycol.find().pretty()
mongos> 

[8단계] 데이터 sharding 활성화

#11 -> mongos> use admin // 다시 admin db 선택
mongos> db.runCommand({“enablesharding”:“myshdb2”})

[9단계] 데이터 sharding

• 컬렉션 수준에서 sharding

• 여기서 shard key는 _id 필드로 지정

#11 -> mongos> db.runCommand({“shardcollection”:“myshdb2.mycol”, “key”:{“_id”:1}})

 

 

반응형
반응형

<기타 지식 >

-안드로이드 P

 : 오레오의 다음 버전, 2018년 3분기에 공개될 새로운 안드로이드 버전.

 1) 와이파이 RTT : 와이파이 Accss Point까지 거리를 측정, 3개 이상의 AP와 거리를 파악해 1-2cm 오차로 장치의 위치 계산 가능 => 건물 내 길 안내, 음성으로 가까운 조명을 켜는 서비스

 2) 디스플레이 컷 아웃 : 아이폰x같은 노치 디자인을 적용한 스마트폰에서 상태표시줄 높이 관리 가능.

 => 이용자의 몰입을 방해하지 않도록 전체화면으로 콘텐츠 표시할 수 있게

 3) 스마트 리플라이 : 그룹대화, 개별대화 식별할 수 있게 함 + 메시지 내용 분석하여 답장 내용 추천

 4) 통화 중 녹음기능 감지 시 상대방에게 알림

 5) 듀얼카메라에 특화 된 기능

 

 

- QR코드란?

 : Quick Response의 약자

작은 공간에 기존 바코드보다 훨씬 많은 데이터를 담을 수 있음

오류 정정 기능이 있어, 일부가 손상되어도 복원이 가능 하다

360도 어느 방향에서나 읽을 수 있다. (3가지의 네모를 통해서)

연결 기능을 지원한다. (여러 QR코드에 나뉘어 저장된 정보를 다른 데이터로 연결 가능)

 

닷넷과 자바의 차이는?

 : (닷넷) ms에서 개발한 windows/mac os프로그램 개발 및 실행 환경

 (자바) 웹 어플리케이션 개발을 위한 플랫폼.

 

모바일 웹과 모바일 앱의 차이는?

 : (모바일 웹) HTML기반 웹 브라우저로 동작

                  (장) 플랫폼에 상관없이 모든 모바일 기기에서 빠르게 접근, 이용 가능
                        (URL, QR CODE, NFC)

                       하나의 웹사이트로 수많은 종류의 모바일 기기 유저가 경험 가능

 (모바일 앱) 디바이스에 설치 후 사용

                 (장) 네트워크 연결 없이도 동작할 수 있도록 개발 가능

                       특정 타겟에 맞춤 컨텐츠 제공 가능

 

- SI와 SM의 차이는?

 : (System Integration) 새로운 시스템 구축을 위해 일정기간 프로젝트를 진행

  새로운 IT개발 기술이나 다양한 개발 경험으로 다양한 분야를 접하며 빠르게 성장할 것

(System Management) 그렇게 구축된 시스템을 오픈 이후에 사용하며 개선사항/ 오류사항에 대한 유지보수

 개발된 시스템을 분석, 필요한 기능을 추가하거나 수정하면서 업무지식에 대한 전문가로 성장

 

- SW개발론에 대해서?

 : (폭포수) 순차적인 소프트웨어 개발 프로세스

 => 요구사항 분석 / 설계 / 구현 / 테스트 / 유지보수

 (애자일) 프로젝트의 방향을 지속적으로 검토, 버그를 고치고 필요한 것을 바꾸며 다시 개발을 진행할 수 있도록 변화에 대처하면서 위험요소를 최소화.

 (V모델) 폭포수 모델의 확장된 형태, 테스트 단계를 추가. 각 개발 단계 검증에 초점하여 오류 줄임

 (프로토타입모델) 요구사항 분석 / 프로토타입 설계 / 프로토타입 개발 / 사용자 평가 / 구현

 (나선형모델) 계획 및 초기 요구 분석/ 1차 위험분석 / 1차 프로토타입 개발 / 1차 사용자 평가 / 처음으로

 

인터넷과 인트라넷의 차이는?

 : (인터넷) 외부와 광범위하게 연결되어있는 여러 개의 네트워크를 묶은 개념

 (인트라넷) 조직이나 단체 내부에서 사용되는 네트워크.

 (엑스트라넷) 인트라넷과 유사하지만 특정 조직의 인트라넷을 사용이 허가된 사람 이외에도 고객, 협력업체 등에서 사용할 수 있도록

 

방화벽이란 무엇인가?

 : 트래픽을 모니터링해 허용하거나 차단하는 툴

 

프레임워크란?

 : 개발할 때 설계 기본이 되는 뼈대나 구조, 환경

 

- XML이란?

 : 확장할 수 있는 표시 언어. 태그를 사용자 임의로 만들 수 있음. 텍스트 기반의 간결한 데이터형.

 Html이 가지는 태그의 한계를 극복. 웹에서 데이터 및 구조화된 문서를 위한 보편적 표준

 

블루투스란

 : 휴대폰이나 그 주변장치를 연결하는 무선 통신 기술. 연결 케이블 없이 전파를 사용하여 데이터를 주고받기 위한 규격.

 

리눅스와 유닉스의 차이는?

 : (리눅스) 유닉스의 장점을 포함한 유닉스와 거의 닮은 운영체제.

 (유닉스) 서버용 운영체제.암호화 능력이 좋고 안정성과 메모리 관리 능력이 좋음.

 

- TCP/UDP 차이는? (TCP/IP 4계층 응용, 전송, 인터넷, 네트워크인터페이스 중 전송계층)

 : (TCP) 연결형 프로토콜로 목적지와 수신지를 확실히 하여 정확한 전송을 보장하기 위해 세션을 수립함. 3 way handshake로 연결을 설정, 4 way handshake로 해제. 높은 신뢰성. UDP보다 속도가 느림. 1:1 통신

 (UDP) 비연결형 프로토콜로 데이터를 빨리 전달 하는 것을 목적으로함. 신뢰성이 낮지만 TCP보다 빠름. 실시간서비스(스트리밍)처럼 연속성이 중요한 서비스에 사용. 1:1 & 1:다 & 다 : 다 통신

 

- IPv6란?

 : IPv4 (32비트) 주소가 모자라 대안으로 제안된 인터넷 프로토콜 => 128비트

 

임베디드 시스템, 임베디드 SW란?

 : 제어가 필요한 시스템 내에 존재하는 시스템, sw이다. 특정목적의 컴퓨터 시스템이며, 전체 장치의 일부분으로 구성,

 

- VPN과 NAT의 차이는?, VPN의 구성요소는?

 : (VPN) Virtual Private Network, 인터넷 네트워크를 이용해 특정 집단만 사용할 수 있는 작은 네트워크 구축. 인터넷 회선을 암호화된 규격을 통해 개인 전용 선 처럼 사용

 (NAT) Network Address Translation, 네트워크 주소 변환

사설 ip주소를 공인 ip주소로 바꿔주는데 사용함.

 

스레드와 프로세스의 차이는?

 : (스레드) 프로세스가 할당 받은 자원을 이용하는 실행 단위, 프로세스 하나가 생성되면 하나의 메인스레드 생성됨. 추가하지 않는 한 모든 코드는 메인스레드에서 실행됨.

 (프로세스) 운영체제로부터 자원을 할당 받는 작업의 단위, 컴퓨터에서 실행중인 프로그램

 

- ERP란?

 : 기업 자원 관리(Enterprise Resource Planning) 기업 전체의 인적, 물적 자원을 효과적이며 통합적으로 관리하며 경영의 효율화와 기업 경쟁력을 강화하는 솔루션입니다. 생산, 판매, 인사, 회계 등 기업의 전반적인 업무 프로세스를 하나의 체계로 구축하며 정보를 공유하고 신속한 업무처리를 도와주는 시스템.

 

- Git, Github

 : (Git) 여러 대의 컴퓨터

 (Github) 여러 대의 컴퓨터가 소통할 수 잇는 서버

 

- “RESTful 하다”의 정확한 의미

 : Representational State Transfer의 약자, REST를 지킨 서비스 디자인

 REST 구성 (자원 = URI, 명령= HTTP Method , 표현 = Representations)

빅오, 오메가, 세타

 (빅오) 최악의 경우, (오메가) 최선의 경우, (세타) 최소와 최악의 중간인 평균복잡도

반응형
반응형

1. Replication(복제)

    => 어떤 기억 장소에서, 데이터를 원형대로 읽어 내어 그 데이터를 동일한 물리적 형식으로 다른 기억 장소에 써 넣는 것

    => 데이터를 여러 db 서버에 분산하여 저장 관리하는 기술

   => 여러 벌의 동일한 데이터베이스를 운영하기위해 필요한 작업

   => 필요에 따라 클라이언트가 메인 서버가 아닌, 복제 서버에 READ 요청을 하도록 설정
         / 메인 서버 부하를 낮추고, 복제된 데이터를 다른 부가적 용도(리포팅, 백업 용도, 재해 복구)로 사용

 

- 왜 복제를 사용하나?

  • To keep your data safe
    • 데이터 안전하게 보관
  • High (24*7) availability of data
    • 24시간 데이터 사용 가능 
  • Disaster recovery
    • 재해 복구
  • No downtime for maintenance (like backups, index rebuilds, compaction)
    • 유지 보수를 위한 다운타임 없음(백업, 인덱스 재구성, 압축)
  • Read scaling (extra copies to read from)
    • 읽기 확장
  • Replica set is transparent to the application
    • 애플리케이션에 레플리카 세트가 투명함

 

-the process of synchronizing data across multiple servers

-provides redundancy and increases data availability with multiple copies of data on different database servers

-protects a database from the loss of a single server. 

   =>fault tolerance

-allows you to recover from hardware failure and service interruptions.

 

몽고디비에서 Replica set 사용

  • Replica set is a group of two or more nodes (generally minimum 3 nodes are required).

    • 2개 이상의 노드로 이루어진 그룹(최소 3개 노드 필요)
  • In a replica set, one node is primary node and remaining nodes are secondary.

    • 한 노드는 기본 노드 , 나머지 노드는 보조 노드
  • All data replicates from primary to secondary node.

    • 모든 데이터는 기본 노드에서 보조 노드로 복제
  • At the time of automatic failover or maintenance, election establishes for primary and a new primary node is elected.

    • 자동 failover또는 유지 보수 시, 기본 노드에 대한 선택이 설정되고, 새로운 기본 노드가 선택
  • After the recovery of failed node, it again join the replica set and works as a secondary node.

    • 실패한 노드를 복구한 후 , 다시 복제본 세트로 들어가 보조 노드로 작동

\

  • replica set(복제 세트)
    • mongoDB에서 사용되는 복제 기술(과거 : 마스터 슬레이브)
    • 같은 데이터를 저장하고, 백업하기 위해 여러 대의 DB 서버가 운영되고, 각각의 서버에 유지하는 복수개의 Mongodb
      인스턴스가 모인 추상적인 그룹
    • 주 노드 1개 / 보조 노드 복수개 사용 가능 
    • A group of mongod instances that maintain the same data set
    • 구성 
      • nodes with data
        1. ONE PRIMARY NODE(DB를 공유시킬 서버(메인)):주노드
          • receives and does all write operations
          •  records all changes to its data sets in its operation log, i.e. oplog (capped collection)
          • 클라이언트 앱들의 쓰기 / 읽기 요청을 모두 받음 . 변화된 모든 내용을 운영 로그 (oplog)에 남김
        2. Secondary nodes(공유되는 DB받을서버(복제 / 백업 공간(여러대 가능)):보조노드
          • apply operations asynchronously using oplog from the primary so that they have the same data set
          • oplog에 기록된 내용들을 동일하게 연산하여 주 노드와 항상 같은 데이터 유지 
      • a node without data(optional)
        1. an arbiter node(PRIMARY / SECONDARY 서버를 모니터링 해주는 역할(끊어지는지 확인 가능)):결정권자
          • 결정권 자는 주 노드의 데이터를 복제하지 않는다 
          • 데이터가 없기 때문에, 주 노드가 될 수 없다
          • 역할 : heartbeat를 통해 노드의 상태를 확인하고 , 유사 시 선거에만 참가

arbiter(결정권자)

 

기본적인 Replica Set 구성

2.  주 노드의 교체 

   => 주 노드와 보조 노드 사이에 주기적으로 주고 받는 heartbeat(=ping/ 2s) 신호 통해 주 노드가 정상적이지 않은 상황 발견하면, 
        나머지 보조 노드들의 선거(election)을 통해 새로운 주 노드를 선발 
   => 원래 주 노드가 정상 상태로 돌아오면, 다시금 주 노드의 역할 맡게 된다 

   => replicate the primary’s oplog and apply the operations to their data sets such that the secondaries’ data sets reflect the primary’s data set

   =>  Replica set members send heartbeats (pings) to each other every 2 seconds. If a heartbeat does not return within 10 seconds, the other members mark the member as inaccessible.

  • 주 노드 서버가 정상인 경우

주 노드 서버 정상

 

  • 주 노드 서버가 정상 작동하지 않는 경우(primary node 대체 : automatic failover)

주 노드 서버가 정상 작동하지 않음

- 보조 노드들은 자신들의 상태, 미리 지정한 Priority  값을 판단하여 어떤 보조 노드가 주 노드로 승격될 것인지 선거

- 만약, 점수가 동일하게 나오면 가장 최근에 반영된 데이터를 반영한 보조 노드가 승격 대상

- 선거가 끝나기 전 까지 Read 수행은 보조 노드를 통해 가능하게 미리 설정(선거 시간 10초 넘기지 않는다)가능,
    Write는 주 노드가 없는 상태이므로 불가능

- 주 노드가 정상 상황 아닌 경우 실패한 write 연산을 retry 하는 기능 있음 

-  If the primary is unavailable, an eligible secondary will hold an election to elect itself the new primary node
    (기본 선거 시간 : 10초)

- The replica set cannot process write operations until the election completes successfully

- The replica set can continue to serve read queries if such queries are configured to run on secondaries while the primary is offline

 

 

3. Read 연산(read preference)

read preference

- 기본적, 응용 프로그램은 읽기 작업을 복제세트의 기본 구성원으로 보냄

   그러나, 클라이언트는 읽기 기본 설정을 지정하여 읽기 작업을 보조로 보낼 수 있다.

- secondary 에 대한 비동기식 복제는 secondary가 primary data 상태를 반영하지 않은 data를 반환한다

- By default, clients read from the primary;
   however, clients can specify a read preference to send read operations to secondaries.

- Asynchronous replication to secondaries means that reads from secondaries may return data that does not reflect the    state of the data on the primary.

 

4. 여러 데이터 센터에 Replica Set 분산

  • 복수의 데이터 센터에 멤버들을 어떻게 분산?
    • 각 DB 노드들을 데이터 센터 분산에서는 멤버(member)로 호칭
    • 데이터 센터의 수를 홀수로 하면, 선거에서 동점이 나올 확률 줄일 수 있다.
    • 각 데이터 센터에는 최소한 1개의 멤버를 배포하는 것이 원칙
    • 주로 서비스를 수행할 데이터 센터와, 대체 운영 및 백업의 목적인 데이터 센터를 결정
    • 주 노드를 뽑는 선거는 모든 멤버 50% 이상의 과반수 득표를 해야 함
    • 과반수의 멤버를 특정 데이터 센터에 분산

 

- EX ) Replica Set 멤버가 5인 경우

Case 1) 2개의 데이터 센터

3개의 멤버는 데이터 센터 1에, 2개의 나머지 2개의 멤버는 데이터 센터 2에 분산한다.

- 만약 데이터 센터 1에 문제가 발생하면, replica set은 READ ONLY가 된다.

- 만약 데이터 센터 2에 문제가 발생하면, 데이터 센터 1의 멤버들의 수는 여전히 과반수가 넘으므로,

   replica set은 WRITE가 가능하다.

Case 2) 3개의 데이터 센터

2개의 멤버는 데이터 센터 1에, 2개의 나머지 2개의 멤버는 데이터 센터 2에, 1개의 멤버는 데이터 센터 3에 배포.

- 만약 어떤 데이터 센터에 문제가 발생하더라도, 나머지 데이터 센터의 멤버들이 선거가 가능한 상황이므로,
   replica set은 WRITE가 가능하다.

 

어느 데이터 센터가 문제가 생기더라도 주 노드의 유지가 가능한 멤버 분포
각 복제 멤버의 우선 순위 설정값을 통해, 주 노드로의 승격 가능성 조정

데이터 센터 수가 많을 수록 멤버들은 고루 분포되기 때문에, 선거 때 동점이 발생할 수 있고, 관리자가 사전에 특정 데이터 센터 내의 멤버들이 선거에서 주 노드로 선택될 확률을 더 많이 주고 싶을 수 있다.

   => 각 멤버 속성을 정의할 때, Priority  값을 미리 정의하여 조정할 수 있다.

 

- EX) Replica Set 멤버가 3인 경우

Case 1) 2개의 데이터 센터

두 개의 멤버는 데이터 센터 1에, 나머지 하나의 멤버는 데이터 센터 2에 둔다. 만약 결정권자(arbiter)를 둔다면, 멤버의 수가 더 많은 데이터 센터 1에 운영한다.

- 데이터 센터 1에 문제가 발생하면, 과반수의 멤버가 불능이 되어, 선거를 할 수 없는 상황이다. 데이터 센터 1이 정상적인 상태로 돌아올 때까지 replica set 자체는 READ ONLY 상태가 된다.

- 데이터 센터 2에 문제가 발생하면, 데이터 센터 1의 멤버들은 과반수이고 선거를 할 수 있으므로, 새로운 주 노드를 선임하여, replica set은 여전히 WRITE가 가능하다.

위와 같이, 데이터 센터 2개의 경우, WRITE가 불가능한 상황이 발생할 수 있기 때문에, 데이터 센터의 수는 최소 3개 이상으로 하는 것이 안전하다.

Case 2) 3개의 데이터 센터

각각의 데이터 센터에는 멤버가 1개씩 존재하는 구조가 된다.

- 데이터 센터 1,2, 3 어디든 문제가 발생하면, 나머지 2개의 멤버들은 선거를 통해 새로운 주 노드를 찾을 것이고, replica set은 여전히 WRITE가 가능하다.

Case 3) 5개의 데이터 센터

각각의 데이터 센터에는 멤버가 1개씩 존재하는 구조가 된다.

replica set 멤버 3 / 활용 연습 도식화

[1단계] 3개 멤버 노드에 대한 데이터 폴더 생성

• c:\data\node1

• c:\data\node2

• c:\data\arbiter

 

[2단계] 3개의 명령창에서 mongod 인스턴스를 각각 실행

• replSet 옵션 : 복제 세트 이름 지정

• bind_ip_all 옵션 : 3대의 컴퓨터 사용시 (local 연습 시에는 불필요)

#1 => c:\> mongod -–port 27111 -–dbpath c:\data\node1 -–replSet myrs -–oplogSize 256

#2  => c:\> mongod -–port 27112 -–dbpath c:\data\node2 -–replSet myrs -–oplogSize 256

#3  => c:\> mongod -–port 27113 -–dbpath c:\data\arbiter -–replSet myrs -–oplogSize 256

 

[3단계] 4번째 명령창에 mongo 쉘로 첫 번째 인스턴스에 접속

#4  => c:\> mongo -–port 27111 . . . >

 

[4단계] 4번째 명령창에서 Replica set 환경 설정 문서를 변수 conf에 저장(여기서, 첫 번째 인스턴스만 멤버로 설정)

#4  => > conf = {_id:”myrs”, members:[{_id:0, host:”localhost:27111”}]} //실제 IP 입력

 

[5단계] 4번째 명령창에서 Replica Set 초기화

#4 = > > rs.initiate(conf) // 복제 세트 초기화

                 . . . .

                 myrs:SECONDARY>

                myrs:PRIMARY>

 

• 출력된 실행 결과 (“ok”:1) 메시지 확인

• 잠시 대기 후 프롬프트 기호 변화 확인

 ->  27111 포트에서 수행 중인 mongod 인스턴스가 프라이머리 노드가 됨

 

[6단계] 4번째 명령창에서 나머지 두 인스턴스를 Replica Set에 추가 후 프롬포트 기호 변경 및 복제 상태 확인(brief summary)

#4  => myrs:PRIMARY> rs.add(“localhost:27112”)

             myrs:PRIMARY> rs.add(“localhost:27113”, {arbiterOnly:true}) 또는

                                             rs.addArb(“localhost:27113”)

            myrs:PRIMARY>

            myrs:PRIMARY> db.isMaster() // 상세 정보 보기는 rs.status() 사용

 

[7단계] 5 또는 6 번째 명령창에 mongo 쉘로 위 인스턴스 중 하나에 접속하여 세컨터리 및 아비터 노드임 확인

#5 => c:\> mongo -–port 27112

            . . .

            myrs:SECONDARY>

 

#6 =>  c:\> mongo -–port 27113

            . . .

           myrs:ARBITER>

 

• 프롬프트 기호 확인(세컨더리 멤버, 아비터 멤버)

[8단계] 4 또는 5번째 명령창에서 Replica Set 용 db 및 컬렉션 확인

# 4 => myrs:PRIMARY> use local // Replica Set 용 db 선택

             myrs:PRIMARY> db.getCollectionNames() // 또는 show Collections

 

[9단계] 4 또는 5번째 명령창에서 Replica Set 멤버 및 멤버 정보 확인

#4 => myrs:PRIMARY> db.system.replset.find().pretty()

 

[10단계] 4 또는 5번째 명령창에서 Replica Set 상태 자세히 확인

#4  => myrs:PRIMARY> rs.status()

 

[11단계] 4번째 명령창 (프라이머리 멤버) 에서 문서 삽입

#4  => myrs:PRIMARY> use sample

              myrs:PRIMARY> db.col.insert({uname:”kim”, age:19})

              myrs:PRIMARY> db.col.find().pretty() 

 

[12단계] 5번째 명령창(세컨더리 멤버) 에서 문서 검색

#5  => myrs:SECONDAY> rs.status()

             myrs:SECONDAY> rs.slaveOk() // 세컨더리 노드에서도 검색 허용

             myrs:SECONDAY> use sample

             myrs:SECONDAY> show collections

             myrs:SECONDAY> db.col.find().pretty()

 

[13단계] 4번째 명령창에서 프라이머리 mongod 멤버 셧다운

• 2 및 3번째 명령창(나머지 두 인스턴스 실행 중)에 출력되는 메시지 확인

#4  => myrs:PRIMARY> use admin

             myrs:PRIMARY> db.shutdownServer()

              . . .

             c:>

 

[14단계] 5번째 명령창(세컨더리 멤버)에서 멤버 상태 재확인

• 이전 프라이머리 및 새로운 프라이머리 확인

#5 => myrs:SECONDAY> rs.status()

           . . .

          myrs:PRIMARY> // 프롬프트 기호가 변화된 것에 주목

 

[15단계]5 번째 명령창(새로운 프라이머리)에서 새로운 문서 삽입

#5 => myrs:PRIMARY> db.col.insert({uname:”cho”, age:23})

           myrs:PRIMARY> db.col.find().pretty() 

 

[16단계] 1번째 창에서 명령창에서 첫 번째 mongod 인스턴스 재실행

#1  => c:\> mongod -–port 27111 -–dbpath c:\data\node1 -–replSet myrs -–oplogSize 256

 

[17단계] 4번째 창에서 mongod 쉘로 위 첫번째 인스턴스에 재접속

#4  => c:\> mongo -–port 27111

              . . .

              myrs:SECONDARY> // 프롬프트 기호 변화 주목

              myrs:SECONDARY> rs.status()

              myrs:SECONDARY> rs.slaveOk()

              myrs:SECONDARY> use sample

              myrs:SECONDARY> show collections

              myrs:SECONDARY> db.col.find().pretty()

 

[17단계] 4 -> 6 -> 5번째 명령창 (mongo쉘) 에서 각 mongod 인스턴스 셧다운

#4   => myrs:SECONDARY> use admin

              myrs:SECONDARY> db.shutdownServer()

              . . .

              > exit

 

#6    => myrs:ARBITER> use admin

               myrs:ARBITER> db.shutdownServer()

                . . .

                > exit

 

#5    => myrs:PRIMARY> myrs:SECONDARY> // 프롬프트 기호 변화 주목

               myrs:SECONDARY> use admin

               myrs:SECONDARY> db.shutdownServer()

              . . .

               > exit

반응형
반응형

1. MongoDB와 JAVA 연동

 

- mongod 인스턴스 및 데이터베이스 연결

// import된 각 패키지들에 대한 설명은 API 문서 참조
import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
public class ConnectToDB {
   public static void main( String args[] ) {

   // Creating a Mongo client
   MongoClient myclient = new MongoClient("localhost" , 27017);

   // 또는 MongoClient myclient = new MongoClient();
   System.out.println("Connected to the database successfully");

   // Accessing the database (db가 없으면 새로 생성)
   MongoDatabase mydb = myclient.getDatabase("sdb");
  }
}

- 컬렉션 생성

import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
public class ConnectToDB {
   public static void main( String args[] ) {
   
   // Creating a Mongo client
   MongoClient myclient = new MongoClient();
   System.out.println("Connected to the database successfully");
   
   // Accessing the database
   MongoDatabase mydb = myclient.getDatabase("sdb");
   
   //Creating a collection
   mydb.createCollection("sampleCol");
   System.out.println("Collection created successfully");
  }
}

- 특정 DB 내의 모든 컬렉션 이름 출력

import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
. . .
public class ListOfCollection {
 public static void main( String args[] ) {
 . . .

 // Accessing the database
 MongoDatabase mydb = myclient.getDatabase("sdb");
 
 // listing all collections
   for (String name : mydb.listCollectionNames()) {
   System.out.println(name);
   }
 }
}

- 컬렉션 선택(반환)

import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.MongoClient;
import org.bson.Document;
public class selectingCollection {
  public static void main( String args[] ) {
   . . .

   // Accessing the database
   MongoDatabase mydb = myclient.getDatabase("sdb");

   // Retrieving a collection
   MongoCollection<Document> mycol = mydb.getCollection("sampleCol");
   System.out.println("Collection Col selected successfully");
  }
}

-컬렉션 제거(drop)

import com.mongodb.client.MongoCollection;
. . .
public class DroppingCollection {
 public static void main( String args[] ) {
 . . .
 // Accessing the database
 MongoDatabase mydb = myclient.getDatabase("sdb");
 
 // Retrieving a collection
 MongoCollection<Document> mycol = mydb.getCollection("sampleCol");
 
 // Dropping a Collection
 mycol.drop();
 System.out.println("Collection dropped successfully");
 }
}

- document삽입

. . .
import org.bson.Document;
public class insertingDocument {
 public static void main( String args[] ) {
 . . .
 // Retieving a collection
 MongoCollection<Document> mycol = mydb.getCollection("sampleCol");
 System.out.println("Collection Col selected successfully");
 
 // bson Document 객체 생성
 Document mydoc = new Document("title", "MongoDB")
 .append("id", 1)
 .append("description", "database")
 .append("likes", 100)
 .append("url", "http://www.tutorialspoint.com/mongodb/")
 .append("by", "tutorials point");
 mycol.insertOne(mydoc);
 System.out.println("Document inserted successfully");
 }
}

-컬렉션 내 모든 문서 검색

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import java.util.Iterator;
. . .
public class RetrievingAllDocuments {
 public static void main( String args[] ) {
 . . .
 // Retrieving a collection
 MongoCollection<Document> mycol = mydb.getCollection("sampleCol");

 // Getting the iterable object
 FindIterable<Document> iterDoc = mycol.find();
 
 // Getting the iterator
 Iterator it = iterDoc.iterator(); // iterator 반환
 int i = 1;
   while (it.hasNext()) {
   System.out.println(it.next());
   i++;
   }
 }
}

-document 수정

import com.mongodb.client.MongoCollection;
import com.mongodb.client.FindIterable;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
. . .
public class UpdatingDocuments {
 public static void main( String args[] ) {
 . . .
 // Updating a document
 mycol.updateOne(Filters.eq("id", 1), Updates.set("likes", 150));
 System.out.println("Document update successfully...");
 
 // Getting the iterable object
 FindIterable<Document> iterDoc = mycol.find();
 
 // Getting the iterator
 Iterator it = iterDoc.iterator(); // iterator 반환
 int i = 1;
   while (it.hasNext()) {
   System.out.println(it.next()); i++;
   }
 }
}

- document 삭제

import com.mongodb.client.MongoCollection;
import com.mongodb.client.FindIterable;
import com.mongodb.client.model.Filters;
. . .
public class DeletingDocuments {
 public static void main( String args[] ) {
 . . .
 // Deleting a document
 mycol.deleteOne(Filters.eq("id", 1)); // deleteMany() 메소드
 System.out.println("Document deleted successfully...");
 
 // Getting the iterable object
 FindIterable<Document> iterDoc = mycol.find();
 int i = 1;
 
 // Getting the iterator
 Iterator it = iterDoc.iterator(); // iterator 반환
   while (it.hasNext()) {
   System.out.println(it.next()); i++;
   }
 }
}

-조건에 맞는 특성 문서 검색

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import java.util.Iterator;
. . .
public class RetrievingAllDocuments {
 public static void main( String args[] ) {
 . . .
 // Retrieving a collection
 MongoCollection<Document> mycol = mydb.getCollection("sampleCol");

 // Finding a document with find(Bson filter) method
 // and Getting the iterable object
 FindIterable<Document> iterDoc = mycol.find(검색조건); // 커서 반환
 //검색 조건 : find() / delete() / update()  조건 표현은 동일 
 //각종 메소드 활용 가능 
 . . .
 }
}

 

-----------------------------------------------------------------------------------------------------------------------------------

자바 연동 과제는 따로 보관 ㅎㅎ

반응형
반응형

React에는 컴포넌트가 로드될 때, 업데이트 될 때 , 제거될 때 자동으로 호출되는 API 가 존재

=> React 의 Life Cycle API 

초기 생성 API

- 브라우저에 컴포넌트가 나타나기 전 호출되는 API

  • Constructor(props) : 컴포넌트 생성자 함수로 컴포넌트가 새로 만들어 질 때마다 호출
  • ComponentWillMount() : 컴포넌트가 화면에 나타나기 직전에 호출되는 API
    -> 주로 서버를 호출하는 용도로 사용되었는데 이 API를 더 필요하지 않다고 판단하여 사용하지 않게 됨 
    기존에 처리하던 부분은 constructor이나 componentDidMount에서 처리할 수 있음
  • componentDidMount() : 컴포넌트가 나타난 후 호출되는 api
    주로 , D3, masonry 처럼 DOM 을 사용하는 외부 라이브러리와 연동하거나, 데이터를 axios , fetch 등 통해 ajax 요청하거나, DOM 속성(스크롤 설정, 크기 등) 읽거나 직접 변경하는 작업 함

업데이트 API

- 로드된 컴포넌트가 props, state 변화로 인해 변경될 경우 호출되는 API 

  • componentWillReceiveProps(nextProps)  :
    자식 component가 부모 Component로 부터 새로운 props 를 받게 되었을 때 호출
    지금 사용되지 않음 -> getDerivedStateFromProps사용
  • static getDerivedStateFromProps(nextProps, prevState) :
    props로 받아온 값을 state로 동기화하는 작업을 해주어야할 경우 사용

    setState로 state 값을 설정하는 것이 아니라, 객체 형태로 state 값 리턴
    업데이트 할 값이 없다면 null 리턴
  • shouldComponentUpdate(nextProps, nextState)  :
    - 컴포넌트 최적화 작업에서 유용 
    - React는 변화가 발생한 DOM 만 찾아 변화시켜주는데 자식 Component가 직접적으로
    변하지 않았어도 부모가 Component가 리렌더링 되면 자식 컴포넌트도 다시 렌더링되며 Virtual Dom에 그려짐 
    - 기존 DOM 과 비교해서 변화가 발생했다면 실제 DOM 이 변경되고 그렇지 않다면 아무 작업도 하지 않음
    - 많은 렌더링 작업 시 부하가 생기고 기본적으로 true 값을 반환하고 우리가 조작하는 상황에 따라 false를 반환
        => render() 함수를 호출하지 않게 되고, Virtual DOM 에 리렌더링하는 작업을 막을 수 있음 
  • componentWillUpdate(nextProps, nextState) : 
    - shouldComponentUpdate에서 true가 반환되었을 때 호출
    - 주로 애니매이션 효과를 초기화하거나, 이벤트 리스너를 없애는 작업 

    - 이 함수 다음에 render 함수가 호출 (업데이트 이후 쓰이지 않음 아래 함수로 대체)
  • getSnapshotBeforeUpdate(prevProps, prevState)
    -  render 함수와 ComponentDidUpdate사이에 호출 
    - DOM 변화가 일어나기 직전의 DOM 상태를 가져오고, 여기서 그 상태 값(snapshot)을 반환해서 ComponentDidUpdate의
       3번째 매개변수로 받아 올 수 있다
    - 예 ) 현재 위치 스크롤바 유지하고 싶을 때 => 이 , api에서 현재 스크롤바 위치를 구해 그 값을 매개 변수로 반환 =>           componentDidUpdate에서 그 인자를 받아 스크롤바 위치 처리를 해주는 식 
    - render -> getShapshotBeforeUpdate -> 실제 DOM 업데이트 -> componentDidUpdate 순 진행
  • componentDidUpdate(prevProps, prevState, snapshot) : 
    - render 함수가 호출된 후 호출 
    - 이 시점에  this.props와 this.state는 변경된 상태 
    - 매개 변수로 받은 prevProps와 prevState는 말 그대로 변경 이전의 props와 state 값

제거 api

- 컴포넌트가 더 이상 사용되지 않을 경우 호출되는 api 

  • componentWillUnmount() : 
    - 주로 이벤트 제거 , setTimeout 의 clearTimeout 통한 제거 , setinterval의 clearInterval 통한 제거 작업
    - 외부 라이브러리 사용 시, 이 부분에서 해당 라이브러리의 dispose 기능 실행

src/StopWatch.js 수정 (기존 코드 + 주석 범위 안에 life cycle api 추가)

// StopWatch.js
import React, { Component } from "react";
 
class StopWatch extends Component {
  // class fields
  state = {
    sec: 0,
    buttonFlag: true,
    intervalFunction: null
  };
 
  /* Life Cycle API 영역 시작 */
  constructor(props) {
    super(props);
    console.log("constructor");
  }
 
  componentWillMount() {
    console.log("componentWillMount");
  }
 
  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate");
    if (nextState.sec % 2 === 0) {
      console.log(`${nextState.sec} % 2 === 0`);
      return false;
    }
    return true;
  }
 
  componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate");
  }
 
  componentDidUpdate(prevProps, prevState) {
    console.log("componentDidUpdate");
  }
 
  /* Life Cycle API 영역 끝 */
 
  // stop watch 로직
  timer = () => {
    // 비구조화 할당 사용( { sec } 부분 )
    this.setState(({ sec }) => ({
      sec: sec + 1
    }));
  };
 
  // start 버튼 클릭
  start = () => {
    this.setState({
      sec: 0,
      buttonFlag: false,
      intervalFunction: setInterval(this.timer, 1000)
    });
  };
 
  // stop 버튼 클릭
  stop = () => {
    clearInterval(this.state.intervalFunction);
 
    this.setState({
      buttonFlag: true
    });
  };
 
  render() {
    return (
      <React.Fragment>
        <h1>Stop Watch</h1>
        <div>
          <b>{this.state.sec}</b>
          <span>초</span>
          {this.state.buttonFlag ? (
            <button onClick={this.start}>start</button>
          ) : (
            <button onClick={this.stop}>stop</button>
          )}
        </div>
      </React.Fragment>
    );
  }
}
 
export default StopWatch;

 

=> state 내의 sec가 0,2,4 즉, 짝수일 경우 컴포넌트를 변화시키지 않으므로 shouldComponentUpdate 까지만 호출
     실제 변화는 발생하지 않는다 / sec가 5 -> 6으로 변할 때 , stop 버튼을 눌러 state 안에 buttonFlag 값이 바뀌어
     마지막에 컴포넌트의 변화가 일어남

 

에러 처리 api

-render 함수 안에 에러가 발생하면, react 앱 기능이 정지  / 이 현상을 막기 위해 사용하는 api

 

  • componentDidCatch(error, info) :
    - render 함수 안에 에러가 발생 시 , 호출
    - state 에 error 이라는 변수를 생성 -> 해당 api 호출 시 setState로 error 값을 변경하여 render 함수 쪽에
       다시 에러용 UI를 보여줌
    - 주의점 : Component 자신의 render 함수에서 발생하는 에러는 잡을 수 없고, 자식 Component 내부의 render 함수에서 발생하는 에러를 잡음

src/StopWatch.js

-> ErrorMaker라는 인위적으로 에러를 생성하는 컴포넌트를 함수형 컴포넌트 형식으로 생성

    StopWatch 내부에서는 state의 인자로 error라는 값이 추가되었고 Life Cycle API 영역에서 마지막에 componentDidCatch가        추가.

     render 함수에서는 앱 중지를 방지하는 코드가 추가되었고, state의 sec가 3이 되었을 때, ErrorMaker를 생성.

// StopWatch.js
import React, { Component } from "react";
 
// Error 생성용 자식 Component
const ErrorMaker = () => {
  throw new Error("Error Occured!!");
  return <div />;
};
 
class StopWatch extends Component {
  // class fields
  state = {
    sec: 0,
    buttonFlag: true,
    intervalFunction: null,
    error: false
  };
 
  /* Life Cycle API 영역 시작 */
  constructor(props) {
    super(props);
    console.log("constructor");
  }
 
  componentWillMount() {
    console.log("componentWillMount");
  }
 
  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate");
    if (nextState.sec % 2 === 0) {
      console.log(`${nextState.sec} % 2 === 0`);
      return false;
    }
    return true;
  }
 
  componentWillUpdate(nextProps, nextState) {
    console.log("componentWillUpdate");
  }
 
  componentDidUpdate(prevProps, prevState) {
    console.log("componentDidUpdate");
  }
 
  // render에서 에러 발생시 호출
  componentDidCatch(error, info) {
    console.log("componentDidCatch");
    this.setState({
      error: true
    });
  }
 
  /* Life Cycle API 영역 끝 */
 
  // stop watch 로직
  timer = () => {
    // 비구조화 할당 사용( { sec } 부분 )
    this.setState(({ sec }) => ({
      sec: sec + 1
    }));
  };
 
  // start 버튼 클릭
  start = () => {
    this.setState({
      sec: 0,
      buttonFlag: false,
      intervalFunction: setInterval(this.timer, 1000)
    });
  };
 
  // stop 버튼 클릭
  stop = () => {
    clearInterval(this.state.intervalFunction);
 
    this.setState({
      buttonFlag: true
    });
  };
 
  render() {
    // 다음과 같이 에러 발생시에 앱이 중지되는 것을 방지한다.
    if (this.state.error) return <h1>에러 발생!!</h1>;
 
    return (
      <React.Fragment>
        <h1>Stop Watch</h1>
        {this.state.sec === 3 && <ErrorMaker />}
        <div>
          <b>{this.state.sec}</b>
          <span>초</span>
          {this.state.buttonFlag ? (
            <button onClick={this.start}>start</button>
          ) : (
            <button onClick={this.stop}>stop</button>
          )}
        </div>
      </React.Fragment>
    );
  }
}
 
export default StopWatch;

결과는?

x 버튼 누르면 다음과 같이 에러 발생 시 정해둔 ul 가 나타남
-> 에러 발생하는 이유는 

    - 존재하지 않는 함수를 호출하려고 할 때(props로 받은 줄 알았던 함수 호출할 때)

    - 배열이나 객체를 받을 줄 알았을 때 존재하지 않을 때

 

render() {
    // 에러를 유발시키는 유형(실제로 props에서 onClick(), object, array를 받지 않았다고 가정)
    /*
        this.props.onClick();
        this.props.object.value;
        this.props.array.length;
    */
 
    // 다음과 같은 분기문을 추가하여 에러를 방지한다.
    if( !this.props.object || this.props.array || this.props.array.length === 0 ) return null;
 
    // ...
}

 혹시 누락 발생할 거 같으면 다음과 같이 defaultProps를 이용해 해당 값들을 초기화해서 사용

class Test extends Component {
    static defaultProps = {
        onClick: () => console.warning("onClick is not defined"),
        object: {},
        array: []
    }    
}

 

인용

https://dev-kani.tistory.com/11?category=849014
반응형

'Language Study > React' 카테고리의 다른 글

3. props와 state  (0) 2019.11.26
2. JSX  (0) 2019.11.26
1. 준비사항  (0) 2019.11.26
반응형

React Component에서 다루는 데이터는 props와 state

 

props

자식 Component가 생성될 때 부모 Component에서 받아온 데이터로 변경이 불가능

자식 Component에서 this라는 키워드를 통해 부모 Component로부터 받은 props를 사용할 수 있음

 

src/Card.js

// Card.js
import React, { Component } from "react";
 
class Card extends Component {
  render() {
    return (
      <React.Fragment>
        <h3>
          이름 : <b>{this.props.name}</b>
        </h3>
        <h3>
          소속 : <b>{this.props.department}</b>
        </h3>
        <h3>
          연락처 : <b>{this.props.phone}</b>
        </h3>
        <h3>
          이메일 : <b>{this.props.email}</b>
        </h3>
      </React.Fragment>
    );
  }
}
 
export default Card;

scr/App.js 수정

// App.js
import React, { Component } from "react";
import Card from "./Card";
 
class App extends Component {
  render() {
    return (
      <Card
        name="jisu"
        department="Dev"
        phone="010-1234-5678"
        email="282532@naver.com"
      />
    );
  }
}
 
export default App;

Card가 App의 자식 Component가 되는 것
이 때, 부모Component(App.js) 에서 지정한 name, department, phone, email

-> 자식Component(Card.js)로 전달되어 

Card에서 this.props.name, this.props.department, this.props.phone, this.props.email이 사용

 

<defaultProps>

- 부모 Component 가 여러 개의 공통된 자식 Component 를 사용할 경우

 -> 하지만, 자식 Component에서 공통적으로 사용되는 props와 값이 다양한 props가 있을 수 있다

- 이 경우 , 자식 Component에서 defaultPorps를 이용하여 props의 기본값을 설정해 줄 수 있음

- 기본값 : 부모 Component에서 지정해 줄 경우 지정한 값으로 지정하지 않으면 기본값으로 props가 적용

 

//Card.js

import React, { Component } from "react";
 
class Card extends Component {
  static defaultProps = {
    department : "Dev"
  };

  render() {
    return (
      <React.Fragment>
        <h3>
          이름 : <b>{this.props.name}</b>
        </h3>
        <h3>
          소속 : <b>{this.props.department}</b>
        </h3>
        <h3>
          연락처 : <b>{this.props.phone}</b>
        </h3>
        <h3>
          이메일 : <b>{this.props.email}</b>
        </h3>
      </React.Fragment>
    );
  }
}
 
export default Card;

//App.js

// App.js
import React, { Component } from "react";
import Card from "./Card";
 
class App extends Component {
  render() {
    return (
      <React.Fragment>
        {/* department 생략 */}
        <Card name="jisu" phone="010-1234-5678" email="282532@naver.com" />
        <hr />
        {/* department 포함 */}
        <Card
          name="joby"
          department="Marketing"
          phone="010-5678-9123"
          email="bob@bob.com"
        />
      </React.Fragment>
    );
  }
}
 
export default App;

<Functional Component(함수형 컴포넌트)>

- 클래스형 컴포넌트 외 다른 방법으로 컴포넌트 생성

- 단순히 props 받아오는 컴포넌트의 경우 더 간단한 문법으로 사용 가능

- 함수형 컴포넌트는 컴포넌트가 함수이기 때문에 클래스의 특성에서 지닐수 있는 static이나 this 키워드를 사용할 수 없음

-  state나 Life Cycle과 관련된 함수를 사용할 수 없습니다.

 

//Card.js => 함수의 매개변수로 props의 인자들 직접 받음 

 

// Card.js
import React from "react";
 
const Card = ({ name, department, phone, email }) => {
  return (
    <React.Fragment>
      <h3>
        이름 : <b>{name}</b>
      </h3>
      <h3>
        소속 : <b>{department}</b>
      </h3>
      <h3>
        연락처 : <b>{phone}</b>
      </h3>
      <h3>
        이메일 : <b>{email}</b>
      </h3>
    </React.Fragment>
  );
};
 
// 기본 props 지정(함수형 컴포넌트 사용시 static을 사용불가)
Card.defaultProps = {
  department: "Dev"
};
 
export default Card;

state

-  Component 내부에서 생성된 데이터로 변경이 가능

- Component 내부에 state를 class field나 constructor(props) 내부에 정의해서 사용

 

Method Binding

- 이벤트 처리할 경우 , 임의의 메소드 생성

- 이 때, 해당 메소드에서 state를 변경하기 위해 this 키워드를 사용하려면 메소드에 this를 바인딩 시켜주어야

- constructor(props) 내부에 "this.메소드명 = this.메소드명.bind(this)"를 사용하여 메소드에 this를 바인딩

=> 이 작업이 없을 경우, 이벤트가 발생 시 해당 메소드가 이벤트로 전달되는 과정에서 this와 연결이 끊어져, undefined가 됨

      하지만, this 를 메소드로 화살표 함수 표현(Arrow Function Expression)으로 만들 경우,
      this 가 풀리는 것에 대해 걱정할 필요가 없기에 method binding 명시적으로 하지 않아도 됨

 

 

setState

- 선언된 state 값을 변경하기 위해서는 무조건 this.setState를 사용 /
   React 내부에서 setState를 호출하게 되면 자동으로 Component를 리렌더링하게 설계

- 객체로 전달되는 해당 값만 state에서 변경. 전달되지 않은 값은 기존값으로 유지.
   state 내부에 객체가 존재하고 그 객체의 특정 인자만 변경하고 싶다면
  "객체1: { ..., this.state.객체1, 변경요소: 변경요소 값 }"의 다음과 같은 구조로 작성

   =>  그렇지 않으면 객체 자체를 새로 덮어 써버림

 

 전개 연산자(Spread Operator, ...)을 사용하면 기존 내용을 해당 객체에 풀어줌.

 - 이 부분은 객체의 depth가 깊어지면 상당히 복잡해지므로 immutable.js나 immer.js를 이용해서 간단화 작업을 하는게 좋음

 - 기존의 값을 토대로 새로운 값으로 변경하고 싶을 땐 "값1: this.state.값1" 이런 식으로 처리.

     =>  this.state를 사용하고 싶지않다면 setState를 화살표 함수로 만들어서 매개변수로 state나 해당 값을 넣어주면 됨.

    이 때, 해당 값을 이용할 땐 비구조화 할당(Destructuring Assignment)이라는 문법을 사용합니다.

 - render() 함수 내부의 HTML 코드에서 이벤트를 설정할 땐, camelCase로 이벤트명을 적어야 함

  - 또한 이벤트 속성의 값으로는 "함수()" 형태가 아닌 "함수명"으로

     => 그렇지 않을 경우 함수 호출이 무한 루프에 빠질수 있습니다. (렌더링 -> 함수 호출 -> setState -> 리렌더링 -> 함수 호출 -> ...)

 

src/StopWatch.js

// StopWatch.js
import React, { Component } from "react";
 
class StopWatch extends Component {
  // class fields
  state = {
    sec: 0,
    buttonFlag: true,
    intervalFunction: null
  };
 
  // stop watch 로직
  timer = () => {
    // 비구조화 할당 사용( { sec } 부분 )
    this.setState(({ sec }) => ({
      sec: sec + 1
    }));
  };
 
  // start 버튼 클릭
  start = () => {
    this.setState({
      sec: 0,
      buttonFlag: false,
      intervalFunction: setInterval(this.timer, 1000)
    });
  };
 
  // stop 버튼 클릭
  stop = () => {
    clearInterval(this.state.intervalFunction);
 
    this.setState({
      buttonFlag: true
    });
  };
 
  render() {
    return (
      <React.Fragment>
        <h1>Stop Watch</h1>
        <div>
          <b>{this.state.sec}</b>
          <span>초</span>
          {this.state.buttonFlag ? (
            <button onClick={this.start}>start</button>
          ) : (
            <button onClick={this.stop}>stop</button>
          )}
        </div>
      </React.Fragment>
    );
  }
}
 
export default StopWatch;

src/App.js

// App.js
import React, { Component } from "react";
import StopWatch from "./StopWatch";
 
class App extends Component {
  render() {
    return <StopWatch />;
  }
}
 
export default App;

 

반응형

'Language Study > React' 카테고리의 다른 글

4. Life Cycle API  (0) 2019.11.26
2. JSX  (0) 2019.11.26
1. 준비사항  (0) 2019.11.26

+ Recent posts