Horizontal 스케일링(aka Scaling out)은 새로운 수요에 대응하기 위해 인프라에 노드나 머신을 추가하는 것을 말합니다. 서버에서 애플리케이션을 호스팅하고 있는데 더 이상 트래픽을 처리할 수 있는 용량이나 기능이 없다는 것을 알게 되면 서버를 추가하는 것이 해결책이 될 수 있습니다.
Vertical 스케일링(aka Scaling up)은 수요를 충족시키기 위해 시스템에 추가적인 자원을 추가하는 것을 말합니다. 이것이 수평 스케일링과 어떻게 다를까요?
https://www.cloudzero.com/blog/horizontal-vs-vertical-scaling/
파란색 장점, 빨간색 단점?
RDBMS는 데이터 구조가 명확하며 변경 될 여지가 없으며 명확한 스키마가 중요한 경우 사용하는 것이 좋습니다. 또한 중복된 데이터가 없어(데이터 무결성) 변경이 용이하기 때문에 관계를 맺고 있는 데이터가 자주 변경이 이루어지는 시스템에 적합합니다.
NoSQL은 정확한 데이터 구조를 알 수 없고 데이터가 변경/확장이 될 수 있는 경우에 사용하는 것이 좋습니다. 또한 단점에서도 명확하듯이 데이터 중복이 발생할 수 있으며 중복된 데이터가 변경될 시에는 모든 컬렉션에서 수정을 해야 합니다. 이러한 특징들을 기반으로 Update가 많이 이루어지지 않는 시스템이 좋으며 또한 Scale-out이 가능하다는 장점을 활용해 막대한 데이터를 저장해야 해서 Database를 Scale-Out를 해야 되는 시스템에 적합합니다.
https://khj93.tistory.com/entry/Database-RDBMS%EC%99%80-NOSQL-%EC%B0%A8%EC%9D%B4%EC%A0%90
Atomicity
: 분해할 수 없이 원자적이고
Consistency
: 일관된 데이터를 유지하고
Isolation
: 고립되어 다른 연산이 끼어들 수 없고
Durability
: 데이터가 영원히 반영된 상태로 있는
ACID 트랜잭션은 관계형 데이터베이스에서 여러 개의 SQL연산을 하나의 단일 트랜잭션으로 처리하는 것을 의미한다. 여러개의 테이블에 대해서 읽고 쓰고 하는 행동을 하나의 연산처럼 사용하는 것이다.
Atomicity
은 여러개의 SQL 연산이 하나의 연산처럼 동작해야 한다. 어느것 하나라도 실패했다면 모든 연산이 실행되지 않아야 한다.
Consistency
은 같은 시점에 접속하는 클라이언트들은 항상 같은 데이터를 보고 있어야 한다는 것
Isolation
은 트랜잭션이 수행되는 동안에 다른 연산이 끼어들지 못한다는 것
Durability
은 트랜잭션이 완료된 이후의 데이터는 업데이트된 상태로 그대로 영원히 반영되어 있다 는 뜻
Consistency
: 데이터를 저장하는 장비가 1대든 100대든 모든 장비에는 동일한 데이터가 저장되어 있어야 한다는 것. ACID 트랜잭션에서 의미하는 것이기도 하다. 어떤 데이터베이스의 속성에 C가 있다면 트랜잭션 기능 혹은 그와 비슷한 매커니즘이 존재한다는 뜻
Availability
: 죽지 않은 상태의 모든 서버는 클라이언트에게 항상 정상 처리 응답을 보내주어야 한다는 뜻. 현재 시스템에 문제가 있어서 읽거나 쓸수 없다고 보내면 가용성이 보장되지 않는 것이다.
Partitions
: 클러스터가 여러대 동작하고 있을 때 해당 클러스터 사이에 접속이 단절되어 서로 통신을 할 수 없는 상황에서도 시스템이 잘 동작해야한다는 뜻
동시에 3가지 적용하는 것은 매우 어렵다.
상대적인 trade-off를 예상할 수 밖에 없다.
관계형 데이터베이스가 동시에 다량의 서버를 운용하는 클러스터링에 적합하지 않는 이유?
관계형 데이터베이스는 CA 시스템이다. 일관성과 가용성은 보장하되 분단 허용성은 보장하지 않는다. 그 이유는 10대의 서버중에서 5번 서버가 접속이 끊겼다. CA라서 P는 지원하지 않으니까 전체 시스템이 잘 동작하지 않는건 이해한다.
근데 CA를 지원하려면 연결이 끊어진 5번 서버 떄문에 나머지 서버를 중단시켜야 CA를 만족하게 된다. 근데 비효율적이고 거의 불가능하다.
결국 관계형 데이터베이스는 클러스터링으로 만들기가 어렵다.
해결책은?
간단하다 CA를 버리면 된다. 버린다는게 극단적으로 false라는 개념이 아닌 100%지원이라면 60%지원으로 변경한다는 의미다. NoSQL은 대부분 CA가 아닌 CP나 AP시스템이다. C가 들어간다면 하나의 쓰기 작업에 100대가 있다면 100대 모두 lock이 걸리게 된다. 응답속도가 매우 안좋음.
https://namoeye.tistory.com/entry/ACID-%EA%B7%B8%EB%A6%AC%EA%B3%A0-CAP%EA%B0%9C%EB%85%90
먼저 일관성과 가용성을 최적화하는 시스템이 있습니다. 이는 분할 허용성을 희생함으로써 달성됩니다.
다시 말해, 우리는 비교적 적은 다운타임(시스템이 작동하지 않는 시간)으로 높은 일관성을 달성할 수 있지만, 네트워크 문제로 전체 시스템이 다운되거나 적어도 개별 트랜잭션 실패의 위험이 있습니다.
우리가 방금 언급한 것처럼 CA 시스템은 일반적으로 전통적인 관계형 데이터베이스인 SQL, Postgres 또는 Oracle을 기반으로 합니다.
다음으로, 일관성과 분할 허용성을 우선시하는 시스템이 있습니다. 이는 가용성을 희생함으로써 달성됩니다.
따라서 우리는 일관성을 유지하고 네트워크 문제에 대처할 수 있지만, 특정 순간에는 일부 데이터가 사용할 수 없어질 가능성이 있습니다.
가장 흔한 CP 시스템의 예는 MongoDB입니다. MongoDB는 인기 있는 ACID(원자성, 일관성, 고립성, 지속성)을 준수하는 NoSQL 데이터베이스입니다.
마지막으로, 가용성과 분할 허용성을 중시하는 시스템이 있습니다. 다시 말해, 데이터는 항상 사용 가능하며 장애가 발생해도 계속해서 이용할 수 있습니다. 그러나 이를 달성하기 위해서는 검색된 데이터가 부정확하거나 오래된 상태이거나 일관성이 없을 가능성이 있습니다.
가장 일반적인 AP 시스템의 예로는 CouchDB와 Cassandra가 있습니다.
https://budibase.com/blog/data/cap-vs-acid/
In MongoDB, databases hold collections of documents.
The field name
var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"), // ObjectId: primary key
name: { first: "Alan", last: "Turing" }, // embedded document
birth: new Date('Jun 23, 1912'), // Date type
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ], // string array
views : NumberLong(1250000) // NumberLong type
}
import {MongoClient} from 'mongodb';
export async function connect() {
const url = "mongodb://localhost:27017/my_database";
let db;
try {
db = await MongoClient.connect(url);
} catch (err) {
// Error Handling
}
return db;
}
Select a DB
<db>
// If there is none, create itUse: create DATABASE
Create a DB (myNewDB) and the collection (myCollection)
export async function insertDocuments
(db) {
// Get the documents collection
const collection = db.collection('restaurants')
// Insert some documents
const result = await collection.insertMany([ {
name: 'Sun Bakery Trattoria',
stars: 4,
categories: [
'Pizza', 'Pasta', 'Italian', 'Coffee', 'Sandwiches'
]
}, {
name: 'Blue Bagels Grill',
stars: 3,
categories: [
'Bagels', 'Cookies', 'Sandwiches'
]
}
])
return result
}
db.<collection>.insertOne({<field>:<value>})
db.<collection>.insertMany()
db.<collection>.find(query, projection)
<table>
db.<collection>.updateOne(filter, update, options)
db.<collection>.updateMany(filter, update, options)
db.<collection>.replaceOne(filter, update, options)
db.<collection>.deleteOne()
db.<collection>.deleteMany()
connect, find 할때 await가 기본적으로 붙는다는 것
(<field1>: <value1>, <field2>: { <operator>: <value> },)
db.inventory.insertMany([
{ item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
{ item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
{ item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
{ item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
{ item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
SELECT * FROM inventory
SELECT * FROM inventory WHERE status in ("A", "D")
SELECT * FROM inventory WHERE status = "A" AND qty < 30
SELECT * FROM inventory WHERE status = "A" OR qty < 30
설마 쿼리문에서 js 코드로 바꾸라는거 나오지는 않겠지만 알고는 있기
index는 도큐먼트를 쿼리해오기 위한 작업량을 줄임
모든 MongoDB의 컬렉션은 기본적으로 _id 필드에 인덱스가 존재
mongodb는 _id 를 기반으로 기본 인덱스 생성
Document의 필드들에 index 를 걸면, 데이터의 설정한 키 값을 가지고 document들을 가리키는 포인터 값으로 이뤄진 B-Tree 데이터 구조를 만듬
B-Tree : Balanced Binary search Tree, Binary Search (이진 검색) 으로 쿼리 속도를 검색 속도 개선
Index 생성하기
db.users.createIndex( { score: -1} )
- 1 for ascending index (오름차순)
- -1 for descending index (내림차순)
https://eunsour.tistory.com/72
book = {
title: "MongoDB: The Definitive Guide",
authors: [ "Kristina Chodorow", "Mike Dirolf" ]
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher: {
name: "O’Reilly Media",
founded: "1980",
location: "CA"
}
}
book = {
title: "MongoDB: The Definitive Guide",
authors: [ "Kristina Chodorow", "Mike Dirolf" ]
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "8798486734"
}
publisher: {
_id: "8798486734“,
name: "O’Reilly Media",
founded: "1980",
location: "CA"
}
HeartBeat는 두 서버 사이에 Fail-Over를 가능하게 하는 모듈로서 서버 사이의 Fail-Over 기능을 제공하고자 할 때 사용한다.
같은 테이블 스키마를 가진 데이터를 다수의 데이터베이스에 분산하여 저장하는 방법을 의미합니다.