MySQL 에서 Oracle connect by 구현하기

Oracle에서 Hierarchy 구조를 구현하는 connect by 구문은 없지만, with recursive 문으로 동일하게 구현할 수 있습니다.

 

재귀 공통 테이블 표현식은 자체 이름을 참조하는 하위 쿼리가 있는 식입니다. 예를 들어:

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

 

명령문을 실행하면 간단한 선형 시퀀스를 포함하는 단일 열인 다음 결과가 생성됩니다.

 

+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

 

재귀 CTE(Common Table Expressions)의 구조는 다음과 같습니다.

  •  WITH 절의 CTE가 자신을 참조하는 경우 WITH 절은 WITH RECURSIVE로 시작해야 합니다. (CTE가 자신을 참조하지 않으면 RECURSIVE가 허용되지만 필수는 아닙니다.) 재귀 CTE에 대한 RECURSIVE를 잊은 경우 다음 오류가 발생할 수 있습니다.
ERROR 1146 (42S02): Table 'cte_name' doesn't exist

 

  • 재귀 CTE 하위 쿼리에는 UNION ALL 또는 UNION [DISTINCT]로 구분되는 두 부분이 있습니다.
SELECT ...      -- return initial row set
UNION ALL
SELECT ...      -- return additional row sets

 

  • 첫 번째 SELECT는 CTE에 대한 초기 행을 생성하며 CTE 이름을 참조하지 않습니다. 두 번째 SELECT는 추가 행을 생성하고 FROM 절에서 CTE 이름을 참조하여 재귀합니다. 이 부분이 새 행을 생성하지 않으면 재귀가 종료됩니다. 따라서 재귀적 CTE는 비재귀적 SELECT 부분과 재귀적 SELECT 부분으로 구성됩니다.각 SELECT 부분은 그 자체로 여러 SELECT 문의 합집합이 될 수 있습니다.

CTE 결과 열의 유형은 비재귀적 SELECT 부분의 열 유형에서만 유추되며 열은 모두 null을 허용합니다. 유형 결정의 경우 재귀 SELECT 부분은 무시됩니다.

비재귀 부분과 재귀 부분이 UNION DISTINCT로 구분되면 중복 행이 제거됩니다. 이는 무한 루프를 피하기 위해 전이적 폐쇄(transitive closures)를 수행하는 쿼리에 유용합니다.

 

재귀 부분의 각 반복은 이전 반복에서 생성된 행에서만 작동합니다. 재귀 부분에 여러 쿼리 블록이 있는 경우 각 쿼리 블록의 반복은 지정되지 않은 순서로 예약되며 각 쿼리 블록은 이전 반복이 종료된 이후 또는 다른 쿼리 블록에서 생성된 행에서 작동합니다.

이전에 표시된 재귀적 CTE 하위 쿼리에는 단일 행을 검색하여 초기 행 집합을 생성하는 비재귀적 부분이 있습니다.

SELECT 1

 

CTE 하위 쿼리에는 다음 재귀 부분도 있습니다.

SELECT n + 1 FROM cte WHERE n < 5

 

각 반복에서 해당 SELECT는 이전 행 집합의 n 값보다 하나 더 큰 새 값을 가진 행을 생성합니다. 첫 번째 반복은 초기 행 세트(1)에서 작동하고 1+1=2를 생성합니다. 두 번째 반복은 첫 번째 반복의 행 집합(2)에서 작동하고 2+1=3을 생성합니다. 이것은 n이 더 이상 5보다 작지 않을 때 발생하는 재귀가 끝날 때까지 계속됩니다.

CTE의 재귀 부분이 비재귀 부분보다 열에 대해 더 넓은 값을 생성하는 경우 데이터 잘림을 방지하기 위해 비재귀 부분의 열을 확장해야 할 수 있습니다.

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, 'abc' AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

 

비엄격 SQL 모드에서 명령문은 다음 출력을 생성합니다.

+------+------+
| n    | str  |
+------+------+
|    1 | abc  |
|    2 | abc  |
|    3 | abc  |
+------+------+

 

비재귀적 SELECT가 열 너비를 결정하기 때문에 str 열 값은 모두 'abc'입니다. 결과적으로 재귀 SELECT에 의해 생성된 더 넓은 str 값이 잘립니다.
엄격한 SQL 모드에서 명령문은 오류를 생성합니다.

ERROR 1406 (22001): Data too long for column 'str' at row 1

 

이 문제를 해결하려면 명령문이 잘림이나 오류를 생성하지 않도록 비재귀 SELECT에서 CAST()를 사용하여 str 열을 더 넓게 만듭니다.

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

Now the statement produces this result, without truncation:

+------+--------------+
| n    | str          |
+------+--------------+
|    1 | abc          |
|    2 | abcabc       |
|    3 | abcabcabcabc |
+------+--------------+

 

열은 위치가 아닌 이름으로 액세스됩니다. 즉, 이 CTE에서와 같이 재귀 부분의 열은 위치가 다른 비재귀 부분의 열에 액세스할 수 있습니다.

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, 1 AS p, -1 AS q
  UNION ALL
  SELECT n + 1, q * 2, p * 2 FROM cte WHERE n < 5
)
SELECT * FROM cte;

 

한 행의 p는 이전 행의 q에서 파생되고 그 반대의 경우도 마찬가지이므로 양수 값과 음수 값은 출력의 각 연속 행에서 위치를 바꿉니다.

+------+------+------+
| n    | p    | q    |
+------+------+------+
|    1 |    1 |   -1 |
|    2 |   -2 |    2 |
|    3 |    4 |   -4 |
|    4 |   -8 |    8 |
|    5 |   16 |  -16 |
+------+------+------+

 

일부 구문 제약 조건은 재귀 CTE 하위 쿼리 내에서 적용됩니다.

  • 재귀 SELECT 부분은 다음 구문을 포함해서는 안 됩니다. MySQL 8.0.19 이전에는 재귀 CTE의 재귀 SELECT 부분도 LIMIT 절을 사용할 수 없었습니다. 이 제한은 MySQL 8.0.19에서 해제되었으며 이제 LIMIT가 선택적 OFFSET 절과 함께 이러한 경우에 지원됩니다. 결과 집합에 미치는 영향은 가장 바깥쪽 SELECT에서 LIMIT를 사용할 때와 동일하지만 재귀 SELECT와 함께 사용하면 요청된 행 수가 생성되는 즉시 행 생성을 중지하므로 더 효율적입니다.
  • 이러한 제약 조건은 재귀 CTE의 비재귀 SELECT 부분에는 적용되지 않습니다. DISTINCT에 대한 금지는 UNION 회원에게만 적용됩니다. UNION DISTINCT는 허용됩니다. 
    • Aggregate functions such as SUM()
    • Window functions
    • GROUP BY
    • ORDER BY
    • DISTINCT
  • 재귀 SELECT 부분은 하위 쿼리가 아닌 FROM 절에서만 한 번만 CTE를 참조해야 합니다. CTE 이외의 테이블을 참조하고 CTE와 조인할 수 있습니다. 이와 같은 조인에서 사용되는 경우 CTE는 LEFT JOIN의 오른쪽에 있어서는 안 됩니다.

이러한 제약 조건은 ORDER BY, LIMIT(MySQL 8.0.18 및 이전 버전) 및 DISTINCT의 MySQL 관련 제외를 제외한 SQL 표준에서 비롯됩니다.
재귀 CTE의 경우 재귀 SELECT 부분에 대한 EXPLAIN 출력 행은 Extra 열에 Recursive를 표시합니다.
EXPLAIN이 표시하는 예상 비용은 반복당 비용을 나타내며 총 비용과 상당히 다를 수 있습니다. 옵티마이저는 WHERE 절이 false가 되는 시점을 예측할 수 없기 때문에 반복 횟수를 예측할 수 없습니다.

CTE 실제 비용은 결과 집합 크기의 영향을 받을 수도 있습니다. 많은 행을 생성하는 CTE는 메모리 내 형식에서 디스크 형식으로 변환하기에 충분히 큰 내부 임시 테이블이 필요할 수 있으며 성능이 저하될 수 있습니다. 그럴경우 허용되는 메모리 내 임시 테이블 크기를 늘리면 성능이 향상될 수 있습니다.

  •  

공통 테이블 표현식 재귀 제한

재귀 CTE의 경우 재귀 SELECT 부분에 재귀를 종료하는 조건이 포함되어 있다는 것이 중요합니다. 런어웨이 재귀 CTE를 방지하기 위한 개발 기법으로 실행 시간을 제한하여 강제 종료할 수 있습니다.

  • cte_max_recursion_depth 시스템 변수는 CTE의 재귀 수준 수에 대한 제한을 적용합니다. 서버는 이 변수 ​​값보다 더 많은 수준을 반복하는 모든 CTE의 실행을 종료합니다.
  • max_execution_time 시스템 변수는 현재 세션 내에서 실행되는 SELECT 문에 대한 실행 제한 시간을 적용합니다.
  • MAX_EXECUTION_TIME 옵티마이저 힌트는 나타나는 SELECT 문에 대해 쿼리당 실행 제한 시간을 적용합니다.

재귀 CTE가 재귀 실행 종료 조건 없이 실수로 작성되었다고 가정합니다.

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte
)
SELECT * FROM cte;

기본적으로 cte_max_recursion_depth 값은 1000이므로 CTE가 1000 수준을 초과하여 재귀하면 종료됩니다. 애플리케이션은 요구 사항에 맞게 세션 값을 변경할 수 있습니다.

SET SESSION cte_max_recursion_depth = 10;      -- permit only shallow recursion
SET SESSION cte_max_recursion_depth = 1000000; -- permit deeper recursion

이후에 시작되는 모든 세션에 영향을 미치도록 전역 cte_max_recursion_depth 값을 설정할 수도 있습니다.

쿼리가 느리게 실행되어 반복되는 경우 또는 cte_max_recursion_depth 값을 매우 높게 설정해야 하는 상황에서 깊은 반복을 방지하는 또 다른 방법은 세션당 시간 제한을 설정하는 것입니다. 이렇게 하려면 CTE 문을 실행하기 전에 다음과 같은 문을 실행하십시오.

SET max_execution_time = 1000; -- impose one second timeout

 

또는 CTE 문 자체에 옵티마이저 힌트를 포함합니다.

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte
)
SELECT /*+ SET_VAR(cte_max_recursion_depth = 1M) */ * FROM cte;

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte
)
SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM cte;

MySQL 8.0.19부터 재귀 쿼리 내에서 LIMIT를 사용하여 가장 바깥쪽 SELECT에 반환할 최대 행 수를 지정할 수도 있습니다. 예를 들면 다음과 같습니다.

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte LIMIT 10000
)
SELECT * FROM cte;

 

시간 제한을 설정하는 대신 또는 추가로 이 작업을 수행할 수 있습니다. 따라서 다음 CTE는 10,000개 행을 반환하거나 1초(1000밀리초) 동안 실행한 후(둘 중 먼저 발생하는 경우) 종료됩니다.

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte LIMIT 10000
)
SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM cte;

 

실행 시간 제한이 없는 재귀 쿼리가 무한 루프에 빠지면 KILL QUERY를 사용하여 다른 세션에서 종료할 수 있습니다. 세션 자체 내에서 쿼리를 실행하는 데 사용되는 클라이언트 프로그램은 쿼리를 종료하는 방법을 제공할 수 있습니다. 예를 들어, mysql에서 Ctrl+C를 입력하면 현재 명령문이 중단됩니다.

재귀 공통 테이블 표현식 예제

앞서 언급한 바와 같이 재귀 공통 테이블 표현식(CTE)은 계열 생성 및 계층적 또는 트리 구조 데이터 순회에 자주 사용됩니다. 이 섹션에서는 이러한 기술의 몇 가지 간단한 예를 보여줍니다.

Fibonacci Series Generation

피보나치 수열은 두 개의 숫자 0과 1(또는 1과 1)로 시작하며 그 이후의 각 숫자는 이전 두 숫자의 합입니다. 재귀 공통 테이블 표현식은 재귀 SELECT에 의해 생성된 각 행이 계열의 이전 두 숫자에 액세스할 수 있는 경우 피보나치 수열을 생성할 수 있습니다. 다음 CTE는 0과 1을 처음 두 숫자로 사용하여 10개의 숫자 계열을 생성합니다.

WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS
(
  SELECT 1, 0, 1
  UNION ALL
  SELECT n + 1, next_fib_n, fib_n + next_fib_n
    FROM fibonacci WHERE n < 10
)
SELECT * FROM fibonacci;

CTE는 다음 결과를 생성합니다.

+------+-------+------------+
| n    | fib_n | next_fib_n |
+------+-------+------------+
|    1 |     0 |          1 |
|    2 |     1 |          1 |
|    3 |     1 |          2 |
|    4 |     2 |          3 |
|    5 |     3 |          5 |
|    6 |     5 |          8 |
|    7 |     8 |         13 |
|    8 |    13 |         21 |
|    9 |    21 |         34 |
|   10 |    34 |         55 |
+------+-------+------------+

CTE 작동 방식:

  • n은 행에 n번째 피보나치 수가 포함되어 있음을 나타내는 표시 열입니다. 예를 들어 8번째 피보나치 수는 13입니다.
    fib_n 열은 피보나치 수 n을 표시합니다.
  • next_fib_n 열은 숫자 n 다음의 다음 피보나치 수를 표시합니다. 이 열은 다음 행에 다음 계열 값을 제공하므로 해당 행은 fib_n 열에서 이전 두 계열 값의 합계를 생성할 수 있습니다.
  • 재귀는 n이 10에 도달하면 종료됩니다. 이것은 작은 행 세트로 출력을 제한하기 위한 임의의 선택입니다.

앞의 출력은 전체 CTE 결과를 보여줍니다. 일부만 선택하려면 최상위 SELECT에 적절한 WHERE 절을 추가합니다. 예를 들어 8번째 피보나치 수를 선택하려면 다음과 같이 하십시오.

mysql> WITH RECURSIVE fibonacci ...
       ...
       SELECT fib_n FROM fibonacci WHERE n = 8;
+-------+
| fib_n |
+-------+
|    13 |
+-------+
Date Series Generation

공통 테이블 식은 일련의 연속 날짜를 생성할 수 있으며, 이는 요약 데이터에 표시되지 않은 날짜를 포함하여 계열의 모든 날짜에 대한 행을 포함하는 요약을 생성하는 데 유용합니다.
판매량 테이블에 다음 행이 포함되어 있다고 가정합니다.

mysql> SELECT * FROM sales ORDER BY date, price;
+------------+--------+
| date       | price  |
+------------+--------+
| 2017-01-03 | 100.00 |
| 2017-01-03 | 200.00 |
| 2017-01-06 |  50.00 |
| 2017-01-08 |  10.00 |
| 2017-01-08 |  20.00 |
| 2017-01-08 | 150.00 |
| 2017-01-10 |   5.00 |
+------------+--------+

 

이 쿼리는 일일 판매를 요약합니다.

mysql> SELECT date, SUM(price) AS sum_price
       FROM sales
       GROUP BY date
       ORDER BY date;
+------------+-----------+
| date       | sum_price |
+------------+-----------+
| 2017-01-03 |    300.00 |
| 2017-01-06 |     50.00 |
| 2017-01-08 |    180.00 |
| 2017-01-10 |      5.00 |
+------------+-----------+

그러나 이 결과에는 테이블에 포함된 날짜 범위에 표시되지 않은 날짜에 대한 "구멍"이 포함되어 있습니다. 범위의 모든 날짜를 나타내는 결과는 판매 데이터에 대한 LEFT JOIN과 조인된 해당 날짜 집합을 생성하는 재귀 CTE를 사용하여 생성할 수 있습니다.

날짜 범위 시리즈를 생성하는 CTE는 다음과 같습니다.

WITH RECURSIVE dates (date) AS
(
  SELECT MIN(date) FROM sales
  UNION ALL
  SELECT date + INTERVAL 1 DAY FROM dates
  WHERE date + INTERVAL 1 DAY <= (SELECT MAX(date) FROM sales)
)
SELECT * FROM dates;

 

CTE는 다음 결과를 생성합니다.

+------------+
| date       |
+------------+
| 2017-01-03 |
| 2017-01-04 |
| 2017-01-05 |
| 2017-01-06 |
| 2017-01-07 |
| 2017-01-08 |
| 2017-01-09 |
| 2017-01-10 |
+------------+

CTE 작동 방식:

 

  • 비재귀적 SELECT는 판매 테이블에 포함된 날짜 범위에서 가장 낮은 날짜를 생성합니다.
  • 재귀 SELECT에 의해 생성된 각 행은 이전 행에 의해 생성된 날짜에 하루를 더합니다.
  • 날짜가 판매 테이블에 포함된 날짜 범위에서 가장 높은 날짜에 도달하면 재귀가 종료됩니다.

판매 테이블에 대해 LEFT JOIN을 사용하여 CTE를 조인하면 범위의 각 날짜에 대한 행이 있는 판매 요약이 생성됩니다.

WITH RECURSIVE dates (date) AS
(
  SELECT MIN(date) FROM sales
  UNION ALL
  SELECT date + INTERVAL 1 DAY FROM dates
  WHERE date + INTERVAL 1 DAY <= (SELECT MAX(date) FROM sales)
)
SELECT dates.date, COALESCE(SUM(price), 0) AS sum_price
FROM dates LEFT JOIN sales ON dates.date = sales.date
GROUP BY dates.date
ORDER BY dates.date;

출력은 다음과 같습니다.

 

+------------+-----------+
| date       | sum_price |
+------------+-----------+
| 2017-01-03 |    300.00 |
| 2017-01-04 |      0.00 |
| 2017-01-05 |      0.00 |
| 2017-01-06 |     50.00 |
| 2017-01-07 |      0.00 |
| 2017-01-08 |    180.00 |
| 2017-01-09 |      0.00 |
| 2017-01-10 |      5.00 |
+------------+-----------+

몇 가지 참고 사항:

 

  • 쿼리, 특히 재귀 SELECT의 각 행에 대해 MAX() 하위 쿼리가 실행되는 쿼리가 비효율적입니까? EXPLAIN은 MAX()를 포함하는 하위 쿼리가 한 번만 평가되고 결과가 캐시됨을 보여줍니다.
  • COALESCE()를 사용하면 판매 테이블에서 판매 데이터가 발생하지 않는 날에 sum_price 열에 NULL이 표시되는 것을 방지할 수 있습니다.
Hierarchical Data Traversal

재귀 공통 테이블 표현식은 계층 구조를 형성하는 데이터를 순회하는 데 유용합니다. 회사의 각 직원에 대해 직원 이름과 ID 번호, 직원 관리자의 ID를 표시하는 작은 데이터 세트를 생성하는 다음 명령문을 고려하십시오. 최상위 직원(CEO)의 관리자 ID는 NULL(관리자 없음)입니다.

CREATE TABLE employees (
  id         INT PRIMARY KEY NOT NULL,
  name       VARCHAR(100) NOT NULL,
  manager_id INT NULL,
  INDEX (manager_id),
FOREIGN KEY (manager_id) REFERENCES employees (id)
);
INSERT INTO employees VALUES
(333, "Yasmina", NULL),  # Yasmina is the CEO (manager_id is NULL)
(198, "John", 333),      # John has ID 198 and reports to 333 (Yasmina)
(692, "Tarek", 333),
(29, "Pedro", 198),
(4610, "Sarah", 29),
(72, "Pierre", 29),
(123, "Adil", 692);

결과 데이터 세트는 다음과 같습니다.

 

mysql> SELECT * FROM employees ORDER BY id;
+------+---------+------------+
| id   | name    | manager_id |
+------+---------+------------+
|   29 | Pedro   |        198 |
|   72 | Pierre  |         29 |
|  123 | Adil    |        692 |
|  198 | John    |        333 |
|  333 | Yasmina |       NULL |
|  692 | Tarek   |        333 |
| 4610 | Sarah   |         29 |
+------+---------+------------+

각 직원의 관리 체인(즉, CEO에서 직원으로의 경로)이 포함된 조직도를 생성하려면 재귀 CTE를 사용합니다.

WITH RECURSIVE employee_paths (id, name, path) AS
(
  SELECT id, name, CAST(id AS CHAR(200))
    FROM employees
    WHERE manager_id IS NULL
  UNION ALL
  SELECT e.id, e.name, CONCAT(ep.path, ',', e.id)
    FROM employee_paths AS ep JOIN employees AS e
      ON ep.id = e.manager_id
)
SELECT * FROM employee_paths ORDER BY path;

CTE는 다음 출력을 생성합니다.

 

+------+---------+-----------------+
| id   | name    | path            |
+------+---------+-----------------+
|  333 | Yasmina | 333             |
|  198 | John    | 333,198         |
|   29 | Pedro   | 333,198,29      |
| 4610 | Sarah   | 333,198,29,4610 |
|   72 | Pierre  | 333,198,29,72   |
|  692 | Tarek   | 333,692         |
|  123 | Adil    | 333,692,123     |
+------+---------+-----------------+

CTE 작동 방식:

 

  • 비재귀적 SELECT는 CEO에 대한 행(NULL 관리자 ID가 있는 행)을 생성합니다.
  • 재귀 SELECT에 의해 생성된 더 긴 경로 값을 위한 공간이 있는지 확인하기 위해 경로 열이 CHAR(200)로 확장됩니다.
  • 재귀 SELECT에 의해 생성된 각 행은 이전 행에서 생성된 직원에게 직접 보고하는 모든 직원을 찾습니다. 이러한 각 직원에 대해 행에는 직원 ID와 이름, 직원 관리 체인이 포함됩니다. 체인은 관리자의 체인이며 끝에 직원 ID가 추가됩니다.
  • 재귀는 직원에게 보고하는 다른 직원이 없을 때 종료됩니다.

특정 직원의 경로를 찾으려면 최상위 SELECT에 WHERE 절을 추가합니다. 예를 들어 Tarek과 Sarah에 대한 결과를 표시하려면 해당 SELECT를 다음과 같이 수정합니다.

mysql> WITH RECURSIVE ...
       ...
       SELECT * FROM employees_extended
       WHERE id IN (692, 4610)
       ORDER BY path;
+------+-------+-----------------+
| id   | name  | path            |
+------+-------+-----------------+
| 4610 | Sarah | 333,198,29,4610 |
|  692 | Tarek | 333,692         |
+------+-------+-----------------+

 

유사한 구조와 비교한 공통 테이블 표현식

공통 테이블 표현식(CTE)은 몇 가지 면에서 파생 테이블과 유사합니다.

  • 두 구문 모두 이름이 지정됩니다.
  • 두 구문 모두 단일 문의 범위에 대해 존재합니다.

이러한 유사성으로 인해 CTE와 파생 테이블은 종종 서로 바꿔서 사용할 수 있습니다. 간단한 예로, 다음 문장은 동일합니다.

WITH cte AS (SELECT 1) SELECT * FROM cte;
SELECT * FROM (SELECT 1) AS dt;

그러나 CTE는 파생 테이블에 비해 몇 가지 장점이 있습니다.

  • 파생 테이블은 쿼리 내에서 한 번만 참조할 수 있습니다. CTE는 여러 번 참조될 수 있습니다. 파생 테이블 결과의 여러 인스턴스를 사용하려면 결과를 여러 번 파생시켜야 합니다.
  • CTE는 자체 참조(재귀적)일 수 있습니다.
  • 하나의 CTE는 다른 CTE를 참조할 수 있습니다.
  • CTE는 해당 정의가 문장 안에 포함되지 않고 문장의 시작 부분에 나타날 때 읽기가 더 쉬울 수 있습니다.

CTE는 CREATE [TEMPORARY] TABLE로 생성된 테이블과 유사하지만 명시적으로 정의하거나 삭제할 필요는 없습니다. CTE의 경우 테이블을 생성하는 데 권한이 필요하지 않습니다.

 

'MySQL' 카테고리의 다른 글

MySQL - stored procedure 성능  (0) 2023.06.29
MySQL - Delimiter  (0) 2023.04.10
GCP-Google Cloud Platform-프로젝트 구축  (0) 2022.03.04
mysql /*! */ 의미  (0) 2022.03.02
MySQL Workbech runtimeError 발생 시  (0) 2022.02.23

기존에 데이터센터에서 운영 중인 SQLServer 데이터를 아마존 AWS의 mySQL DB로 데이터 마이그레이션하는 방법을 설명합니다.

 

마이그레이션 방법에는 여러가지가 있습니다.

1) AWS의 DMS를 이용(SCT 활용)

2) ETL 툴을 이용(본 문서에서 사용할 방법)

3) ODBC 활용(MSSQL에서 linked server 구성

 

정의

빅데이터란 거대한 규모(volume), 빠른 속도(velocity), 높은 다양성(variety)을 특징으로 하는 데이터입니다. 이를 3V라고도 합니다.

간단히 말해, 빅 데이터는 특히 새로운 데이터 소스에서 나온 더 크고 더 복잡한 데이터 세트입니다. 이러한 데이터 세트는 너무 방대하여 기존의 데이터 처리 소프트웨어로는 관리할 수 없습니다. 그러나 이러한 방대한 양의 데이터는 이전에 해결할 수 없었던 비즈니스 문제를 해결하는 데 사용될 수 있습니다.

 

빅 데이터의 3대 요소(3V)

양(volume) 데이터의 양이 중요합니다. 빅 데이터를 사용하면 저밀도 비정형 데이터를 대량으로 처리해야 합니다. Twitter 데이터 피드, 웹 페이지나 모바일 앱의 클릭 스트림, 센서 지원 장비와 같이 알려지지 않은 값의 데이터가 여기에 해당될 수 있습니다. 일부 조직의 경우, 데이터 양이 수십 테라바이트가 될 수 있습니다. 아니면 수백 페타바이트가 될 수 있습니다.
속도(velocity) 속도는 데이터가 얼마나 빨리 수신 및 처리되는가를 나타냅니다. 일반적으로 데이터를 디스크에 기록하는 것보다 메모리로 직접 스트리밍할 때 속도가 가장 빠릅니다. 일부 인터넷 지원 스마트 제품은 실시간 또는 거의 실시간으로 작동하기 때문에 실시간 평가 및 조치가 필요합니다.
종류(variety) 종류란 사용 가능한 데이터의 유형 수를 나타냅니다. 기존 데이터 유형은 구조화되어 관계형 데이터베이스에 적합했습니다. 빅 데이터의 등장으로 새로운 비정형 유형의 데이터가 나타났습니다. 텍스트, 오디오 및 비디오 같은 비정형 및 반정형 데이터 유형은 의미를 도출하고 메타 데이터를 지원하기 위해 추가로 전처리가 필요합니다.

빅 데이터의 가치와 진실

지난 몇 년간 value와 veracity라는 두 가지 V가 더 등장했습니다. 데이터는 내재적 가치를 가집니다. 그러나 가치는 발견이 되기 전까지는 무용지물입니다. 중요성: 데이터가 얼마나 진실하고 신뢰할 수 있습니까?

오늘날에는 빅 데이터가 자본이 되었습니다. 세계에서 가장 큰 기술 회사를 생각해 보십시오. 이들이 제공하는 가치의 대부분은 데이터에서 나오고 있으며, 효율성을 높이고 신제품을 개발하기 위해 데이터를 지속적으로 분석하고 있습니다.

최근의 기술 혁신으로 데이터 스토리지 및 컴퓨팅 비용이 대폭 감소하면서 이전보다 더 많은 데이터를 보다 쉽고 저렴하게 저장할 수 있게 되었습니다. 더 많은 양의 빅 데이터를 보다 저렴하고 손쉽게 액세스할 수 있게 되면서 보다 정확하고 정밀하게 비즈니스 결정을 내릴 수 있게 되었습니다.

빅 데이터에서 가치를 찾는 것은 단순히 데이터를 분석하는 일이 아닙니다(분석은 완전히 다른 이점을 제공). 통찰력 있는 분석가, 비즈니스 사용자 및 경영진이 올바른 질문을 던지고, 패턴을 인식하고, 정보에 입각한 가정을 세우고, 행동을 예측해야 하는 전체적인 발견 프로세스입니다.

그렇다면 어떻게 여기까지 올 수 있었을까요?

빅 데이터의 역사

빅 데이터 자체의 개념은 비교적 새로운 것이지만, 대규모 데이터 세트의 기원은 최초의 데이터 센터가 등장하고 관계형 데이터베이스가 개발되는 등 데이터 세상이 막 시작되었던 1960년대와 70년대로 거슬러 올라갑니다.

2005년 무렵 사람들은 Facebook, YouTube 및 기타 온라인 서비스를 통해 사용자가 얼마나 많은 양의 데이터를 생성하고 있는지 깨닫기 시작했습니다. 같은 해에 Hadoop(빅 데이터 세트를 저장하고 분석하기 위해 특별히 개발된 오픈 소스 프레임워크)이 개발되었습니다. NoSQL도 이 기간 동안 인기를 얻기 시작했습니다.

Hadoop(그리고 최근에는 Spark) 같은 오픈 소스 프레임워크의 개발은 빅 데이터를 보다 손쉽게 사용하고 저렴하게 저장할 수 있게 해준다는 점에서 빅 데이터의 성장에 필수적이었습니다. 그 이후로 빅 데이터의 양이 급증했습니다. 사용자는 여전히 방대한 양의 데이터를 생성하고 있지만, 데이터를 생성하는 것은 인간만이 아닙니다.

Internet of Things(IoT)의 출현으로 더 많은 객체와 장치가 인터넷에 연결되어 고객 사용 패턴 및 제품 성능에 대한 데이터를 수집하고 있습니다. 머신러닝의 등장으로 더 많은 데이터가 생성되었습니다.

빅 데이터의 역사는 오래되었지만, 활용은 이제 시작 단계입니다. 클라우드 컴퓨팅으로 빅 데이터 가능성이 더욱 확장되었습니다. 클라우드는 개발자가 임시 클러스터를 손쉽게 가동하여 데이터 하위 집합을 테스트할 수 있도록 진정한 의미에서 탄력적인 확장성을 제공합니다. 또한 그래프 데이터베이스는 분석 속도를 높이고 포괄적인 방식으로 대량의 데이터를 표시할 수 있으므로 점점 더 중요해지고 있습니다.

 

빅데이터의 이점:

  • 빅 데이터를 사용하면 더 많은 정보를 확보할 수 있기 때문에 보다 완벽한 답을 얻을 수 있습니다.
  • 답이 완벽하다는 것은 데이터의 신뢰성이 높아진다는 의미입니다. 따라서 문제 해결에 대한 완전히 다른 접근 방식이 가능합니다.

빅 데이터 사용 사례

빅 데이터는 고객 경험에서 분석에 이르기까지 다양한 비즈니스 활동을 처리하는 데 도움이 될 수 있습니다. 다음은 몇 가지 예일 뿐이고,

제품 개발 Netflix 및 Procter & Gamble 같은 회사는 빅데이터를 사용하여 고객 수요를 예측합니다. 그리고 과거 및 현재의 제품/서비스의 주요 속성을 분류하고 이러한 속성과 옵션의 상업적 성공 간의 관계를 모델링하여 새로운 제품 및 서비스에 대한 예측 모델을 구축하고 있습니다. 또한 P&G는 포커스 그룹, 소셜 미디어, 테스트 시장, 초기 매장 출시의 데이터 및 분석자료를 사용하여 신규 제품을 계획, 생산, 출시합니다.
예측적 유지 보수 장비 고장을 예측할 수 있는 요소는 장비 생산연도, 제조사, 장비 모델과 같은 정형 데이터는 물론, 수백만 개의 로그 항목, 센서 데이터, 오류 메시지, 엔진 온도 등 비정형 데이터 안에도 깊숙이 숨겨져 있을 수 있습니다. 조직들은 문제가 발생하기 전에 잠재적 문제에 대한 이러한 징후들을 분석함으로써 유지 보수를 보다 비용 효율적으로 배치하고 부품 및 장비 가동 시간을 최대화할 수 있습니다.
고객 경험 고객 유치 경쟁이 시작되었습니다. 고객 경험을 명확하게 파악하는 것이 그 어느 때보다 가능해졌습니다. 빅 데이터를 사용하면 소셜 미디어, 웹 방문, 통화 기록 및 기타 소스에서 데이터를 수집하여 상호 작용 경험을 개선하고 제공되는 가치를 극대화할 수 있습니다. 맞춤형 옵션 제공을 시작하고 고객 이탈을 줄이며 문제를 사전에 처리할 수 있습니다.
사기 및 규정 준수 보안은 단순히 소수의 악질 해커가 아닌, 전문 해커들로 이루어진 집단 전체에 맞서는 것입니다. 보안 환경 및 규정 준수 요구사항은 계속해서 진화하고 있습니다. 빅 데이터를 사용하면 데이터에서 사기를 나타내는 패턴을 식별하고 대량의 정보를 집계하여 규제 보고를 훨씬 빠르게 할 수 있습니다.
머신러닝 머신러닝은 현재 가장 주목 받는 주제입니다. 데이터, 특히 빅 데이터는 그 이유 중 하나입니다. 이제는 프로그래밍을 하는 대신에 머신을 훈련시킬 수 있게 되었습니다. 빅 데이터를 사용해 머신러닝 모델을 훈련한 덕분에 다음과 같은 것들이 가능해졌습니다.
운영 효율성 운영 효율성이 항상 중요한 요소라고는 할 수 없지만, 빅데이터가 가장 큰 영향력을 미치는 분야임은 분명합니다. 빅 데이터를 사용하면 생산, 고객 피드백 및 반품, 기타 요인을 분석하고 평가하여 중단을 줄이고 향후 수요를 예측할 수 있습니다. 빅 데이터는 현재 시장 수요에 따라 의사 결정을 개선하는 데 사용할 수도 있습니다.
혁신 주도 빅 데이터를 이용하면 혁신을 실현할 수 있습니다. 인간, 기관, 기업, 그리고 프로세스 사이의 상호 의존성을 연구하고 이러한 인사이트를 활용할 새로운 방법을 결정할 수 있기 때문입니다. 데이터 통찰력을 사용하여 재무 및 계획 고려 사항에 대한 결정을 개선할 수 있습니다. 트렌드와 고객이 원하는 새로운 제품 및 서비스를 조사할 수 있습니다. 동적인 가격 모델을 구현할 수 있습니다. 가능성은 무궁무진합니다.

빅 데이터 과제

빅 데이터는 많은 것을 약속하고 있지만, 해결해야 할 과제가 없지는 않습니다.

먼저 빅 데이터는 크기가 큽니다. 데이터 스토리지를 위한 신기술이 개발되기는 했지만, 약 2년마다 데이터 양의 2배 증가하고 있습니다. 따라서 조직들은 데이터 증가를 따라잡고 데이터를 효과적으로 저장하는 방법을 찾느라 고군분투하고 있습니다.

그러나 데이터를 저장하는 것만으로는 충분하지 않습니다. 데이터는 가치 있게 사용되어야 하고, 이는 큐레이션에 따라 결정됩니다. 클라이언트와 관련이 있고 의미 있는 분석이 가능한 방식으로 구성된 정제 데이터를 확보하려면 많은 작업이 필요합니다. 데이터 과학자는 작업 시간의 50~80%를 실제 사용하기 전에 데이터를 큐레이션하고 준비하는 데 할애하고 있습니다.

마지막으로 빅 데이터 기술은 빠른 속도로 변화하고 있습니다. 몇 년 전만 해도 Apache Hadoop는 빅 데이터 처리에 사용되는 인기 기술이었습니다. Apache Spark는 2014년에 도입되었습니다. 오늘날 두 가지 프레임워크를 조합하는 것이 가장 좋은 접근 방식인 것으로 보입니다. 빅 데이터 기술을 따라 잡는 것은 지속적인 도전입니다.

빅 데이터의 작동 원리

빅 데이터는 새로운 기회와 비즈니스 모델을 열어주는 새로운 통찰력을 제공합니다. 시작을 위해 세 가지 주요 작업이 수행됩니다.

1.  통합
빅 데이터는 서로 다른 종류의 소스와 어플리케이션으로부터 데이터를 수집해 종합합니다. 추출, 변환 및 로드(ETL)와 같은 기존의 데이터 통합 메커니즘은 일반적으로 이러한 작업에 적합하지 않습니다. 테라바이트 또는 페타바이트 규모로 빅 데이터 세트를 분석하려면 새로운 전략과 기술이 필요합니다.

통합하는 동안 데이터를 가져와서 처리하고, 비즈니스 분석가가 분석을 시작할 수 있는 형식으로 포맷팅되었는지 확인해야 합니다.

2.
빅 데이터를 관리하려면 스토리지가 필요합니다. 스토리지 솔루션은 클라우드, 온프레미스 또는 둘 다에서 사용할 수 있습니다. 데이터를 원하는 형식으로 저장하고, 원하는 처리 요구사항과 필요한 프로세스 엔진을 온디맨드 모델을 기반으로 해당 데이터 세트에 적용할 수 있습니다. 많은 사람들이 현재 데이터가 상주하는 위치에 따라 스토리지 솔루션을 선택하고 있습니다. 클라우드는 현재 컴퓨팅 요구사항을 지원하고 필요에 따라 리소스를 가동할 수 있다는 점에서 점차 인기를 얻고 있습니다.

3.  분석
빅데이터에 대한 투자는 데이터를 분석 및 처리할 때 그 가치를 발휘합니다. 다양한 데이터 세트의 시각적 분석을 통해 새로운 명확성을 확보할 수 있습니다. 새로운 발견을 위해 데이터를 추가로 탐색할 수 있습니다. 또한 발견한 내용을 다른 사람들과 공유할 수 있습니다. 머신러닝 및 인공 지능으로 데이터 모델을 구축할 수 있습니다. 데이터를 업무에 활용할 수 있습니다.

빅 데이터 모범 사례

빅 데이터 여정에 도움을 드리기 위해 반드시 기억해야 할 몇 가지 주요 모범 사례를 모아봤습니다. 다음은 성공적인 빅 데이터 토대를 구축하기 위한 지침입니다.

구체적인 비즈니스 목표에 맞춰 빅 데이터 조정 보다 광범위한 데이터 세트를 사용하면 새로운 발견을 할 수 있습니다. 이를 위해서는 지속적인 프로젝트 투자 및 자금 조달을 보장하는 강력한 비즈니스 중심의 맥락을 고려하여 기술, 조직 또는 인프라에 대한 새로운 투자를 결정하는 것이 중요합니다. 올바른 방향으로 가고 있는지 확인하려면 빅 데이터가 우선 순위가 가장 높은 비즈니스 및 IT를 어떻게 지원하고 활성화하는지 알아야 합니다. 전자상거래 기능을 이해하기 위해 웹 로그 필터링 방법을 파악하고 소셜 미디어 및 고객 지원 상호작용에서 감정을 도출하며 통계적 상관 관계를 분석하여 고객, 제품, 제조, 엔지니어링 데이터와의 관련성을 이해하는 것 등을 그 예로 들 수 있습니다.
표준 및 거버넌스로 기술 부족 문제 완화 빅 데이터에 대한 투자 혜택을 받는 데 가장 큰 장애물 중 하나는 기술 부족입니다. 빅 데이터 기술, 고려 사항 및 결정이 IT 거버넌스 프로그램에 추가되도록 하여 이러한 위험을 완화할 수 있습니다. 접근 방식을 표준화하면 비용을 관리하고 리소스를 활용할 수 있습니다. 빅 데이터 솔루션 및 전략을 구현 중인 조직은 기술 요구사항을 조기에 자주 평가하고 잠재적인 기술 격차를 사전에 식별해야 합니다. 기존 리소스를 교육/교차 교육하고, 새로운 인력을 고용하고, 컨설팅 회사를 활용하여 이러한 문제를 해결할 수 있습니다.
CoE(Center of Excellence)를 통해 지식 이전 최적화 CoE 접근 방식을 사용하여 지식을 공유하고 감독을 제어하며 프로젝트 커뮤니케이션을 관리할 수 있습니다. 빅 데이터가 신규 투자이든 확장 투자이든 관계 없이 소프트 및 하드 비용을 기업 전체에서 공유할 수 있습니다. 이 접근 방식을 활용하면 보다 정형화되고 체계적인 방식으로 빅 데이터 기능과 전체적인 정보 아키텍처의 성숙도를 높일 수 있습니다.
가장 큰 이점은 비정형 데이터를 정형 데이터에 따라 조정할 수 있다는 점입니다. 빅 데이터를 자체를 분석하는 것은 확실히 가치가 있습니다. 한편 저밀도 빅 데이터를 현재 이미 사용하고 있는 정형 데이터와 연결하고 통합하면 더 큰 비즈니스 통찰력을 얻을 수 있습니다.
고객, 제품, 장비, 환경 빅 데이터 중 어떤 것을 캡처하든 관계없이 목표는 핵심 마스터 및 분석 요약에 더 많은 관련 데이터 포인트를 추가하여 더 나은 결론을 이끌어내는 것입니다. 예를 들어, 모든 고객의 감정을 최고 고객의 감정과 구별하는 데 차이가 있습니다. 많은 사람들이 빅 데이터를 기존 비즈니스 인텔리전스 기능, 데이터웨어 하우징 플랫폼 및 정보 아키텍처의 완전한 확장으로 보는 이유가 여기에 있습니다.
빅 데이터 분석 프로세스 및 모델은 인간 기반과 머신 기반이 모두 가능하다는 점을 기억하십시오. 빅 데이터 분석 기능에는 통계, 공간 분석, 의미론, 대화형 검색 및 시각화가 포함되어 있습니다. 분석 모델을 사용하면 유형과 소스가 다양한 데이터의 상관 관계를 분석하여 연관성을 밝히고 의미 있는 발견을 할 수 있습니다.
성능을 위한 발견 랩 계획 데이터에서 의미를 발견하는 것은 그렇게 간단한 문제가 아닙니다. 때때로 우리는 우리가 무엇을 찾고 있는지조차 모릅니다. 당연히 예상했겠지만 말입니다. 경영진과 IT는 이러한 "방향 부족" 또는 "명확한 요구사항 부족" 문제를 해결해야 합니다.
이와 동시에 분석가와 데이터 과학자는 주요 비즈니스 지식 격차 및 요구사항을 이해하기 위해 기업과 긴밀하게 협력해야 합니다. 대화식 데이터 탐색과 통계 알고리즘 실험을 수용하려면 고성능 작업 영역이 필요합니다. 샌드박스 환경이 필요한 지원을 받고 적절하게 관리되는지 확인하십시오.
클라우드 운영 모델에 맞게 조정 빅 데이터 프로세스 및 사용자는 반복적인 실험과 실행 중인 프로덕션 작업 모두에 있어 광범위한 리소스에 액세스해야 합니다. 빅 데이터 솔루션에는 트랜잭션, 마스터 데이터, 참조 데이터 및 요약 데이터를 비롯한 모든 데이터 영역이 포함됩니다. 분석 샌드박스는 요청 시 생성이 되어야 합니다. 사전 및 사후 처리, 통합, 데이터베이스 내 요약, 분석 모델링 같은 전체 데이터 흐름을 제어하는 데 있어 리소스 관리가 중요합니다. 잘 계획된 프라이빗 및 퍼블릭 클라우드 프로비저닝 및 보안 전략은 이렇게 변화하는 요구사항을 지원하는 데 핵심적인 역할을 합니다.

 

linux나 unix 등에서 명령중에서 vi mode를 사용하기 위한 설정입니다.

$ set -o vi

 

 

Bash 셸은 GNU Readline을 사용하기 때문에 .bashrc 및 .inputrc에서 옵션을 설정하여 기본 Emacs와 같은 키 바인딩을 원하는지 (예: Ctrl+W  단어 지우기) 또는 vi 사용자에게 친숙한 모달 인터페이스를 사용하는 바인딩입니다.

Bash 및 MySQL 명령줄과 같은 GNU Readline을 사용하는 다른 도구에서 vi 모드를 사용하려면 아래 내용을 .inputrc 파일에 설정한다.

set editing-mode vi

 

Bash에서만 이 모드를 사용하려는 경우  .bashrc에서 다음을 설정한다.

set -o vi

 

다음을 통해 올바르게 적용되었는지 확인할 수 있습니다. 텍스트에 대해 고정 가능한 작업 세트에 대해 현재 사용 가능한 바인딩 목록이 표시됩니다.

$ bind -P

편집 모드의 다른 가능한 값은 emacs입니다. 두 옵션 모두 위의 bind -P 출력에서 ​​설정을 변경합니다.

이렇게 하면 삽입 모드에서 명령줄을 열 수 있지만 Escape 또는 Ctrl+[를 누르면 Vi의 일반 모드 에뮬레이션으로 들어갑니다. Enter는 두 모드 중 하나에 있는 동안 현재 상태에서 명령을 실행합니다. 이 모드에서 가장 많이 사용되는 바인딩은 라인의 위치로 이동하기 위한 키입니다.

 

  • ^ — Move to start of line
  • $ — Move to end of line
  • b — Move back a word
  • w — Move forward a word
  • e — Move to the end of the next word

 

deleting, yanking 및 pasting도 모두 작동합니다. 또한 일반 모드에서 k 및 j를 사용하면 Emacs 모드에서 Ctrl+P 및 Ctrl+N과 같은 방식으로 기록을 반복할 수 있습니다. 


명령줄에서 vi mode를 해제하려면 아래 명령어를 수행합니다.

set -o emacs

 

분산 시스템의 가장 중요한 데이터를 위한 신뢰할 수 있는 분산 키-값 저장소

 

etcd는 분산 시스템 또는 시스템 클러스터에서 액세스해야 하는 데이터를 안정적으로 저장하는 방법을 제공하는 강력하고 일관된 분산 키-값 저장소입니다. 네트워크 파티션 중에 리더 선택을 정상적으로 처리하고 리더 노드에서도 시스템 오류를 허용할 수 있습니다.

 

Simple interface

Read and write values using standard HTTP tools, such as curl

Key-value storage

Store data in hierarchically organized directories, as in a standard filesystem

Watch for changes

Watch specific keys or directories for changes and react to changes in values

 

For details, see Install.

설치

binary 파일로 설치하는 방법과 source를 build하는방법 그리고 패키지로 설치하는 3가지 방법이 있다. 여기서는 binary 파일로 설치하는 방법과 패키지로 설치하는 방법을 설명한다.

1) install binaries

- 파일 다운로드 : Releases

- 압축해제

tar -xf etcd-v3.5.0-linux-amd64.tar

- 환경설정

경로 추가 : 기존 PATH 에 압축해제한 경로추가 또는 압축해제한 파일을 /usr/local/bin 으로 이동

(예제 : mv etcd etcdctl etcdutl /usr/local/bin, 단 /usr/local 에 사용권한이 있어야 함) 

  

- 설치확인

$ etcd --version
etcd Version: 3.5.0
Git SHA: 946a5a6f2
Go Version: go1.16.3
Go OS/Arch: linux/amd64

 

2) 패키지 설치 : 

패키지 설치 version

- etcd server 설치 : etcd

sudo apt install etcd-server

- etcd client 설치 : etcdctl

sudo apt install etcd-client

- 설치확인

$ etcd --version
etcd Version: 3.2.26
Git SHA: Not provided (use ./build instead of go build)
Go Version: go1.13.8
Go OS/Arch: linux/amd64

 

시작하기

etcd 실행하기(참고 etcd version 에 따라 결과값이나 명령어가 상이할 수 있음)

 

패키지로 설치한 etcdctl version은 3.2.26 인데 이 버전에서 etctl put 은 실행이 안됨. 대신 set 을 사용해야 한다. version 에 따라 명령어가 차이가 있음을 알아야 한다. 아래 명령어는 etcd version 3.5 에서 수행한 내용이다.
  1. etcd 실행: foreground 로 etcd가 실행된다. 백그라운드로 실행하려면 etcd &  명령어로 수행한다.
    Note: 화면에 나오는 내용은 log 내용임
$ etcd
{"level":"info","ts":"2021-09-17T09:19:32.783-0400","caller":"etcdmain/etcd.go:72","msg":... }
⋮

 

  1. 다른 터미털에서 etcdctl 명령어로 key-value를 입력
$ etcdctl put greeting "Hello, etcd"
OK

 

  1. key에 대한 value값을 조회
$ etcdctl get greeting
greeting
Hello, etcd

 

etcd 툴

etcd manager 라는 UI 관리 툴로 관리 할 수 있다. 아래 사이트에서 다운로드 하고 설치한다.

http://etcdmanager.io/ 

 

1. 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 설치 - unbutu 22.04  (0) 2022.06.27
CKA 자격증 취득하기 - 시험예상 문제  (0) 2022.06.09
쿠버네티스 보충  (0) 2022.06.08
CKA 자격증 취득하기 #2  (0) 2022.05.23
CKA 자격증 취득하기 #1  (0) 2022.05.18

Install Kubernetes Cluster on Ubuntu 22.04 with kubeadm

[ 설치환경 ]

- OS : Ubuntu 22.04 LTS(2 CPU, 4GB Memory, 20GB Disk 이상)

- master node : 1대(hostname : master)

- worker node : 2대(hostname : worker-1, worker-2)

 

설치순서

✔  공통 설치(master node, worker node 에 설치)

1) CRI 설치

2) kubeadm, kubectl, kubelet 설치

3) CNI 설치

 

 master node

- kubeadm init 실행

 

 worker node

- kubeadm join 실행

 

 

1. 공통 설치(master node, worker node 에 설치)

1) CRI  설치(Container Runtime Interface)

도커 이미지를 관리해주는 CRI를 설치합니다. CRI는 많은 종류가 있는데 본 문서에서는 containerd 를 설치합니다.

sudo apt-get update
sudo apt-get install containerd

 

2) kubernetes 설치 전 환경설정

- br_netfilter 모듈을 로드합니다.  br_netfilter 모듈이 로드되었는지 확인하려면

lsmod | grep br_netfilter 를 실행하면 됩니다.(kubernetes documents 에서 "container runtimes"로 검색)

sudo modprobe br_netfilter

- iptables가 브리지된 트래픽을 보게 하기

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

- ip_forward 설정

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

 

- swap off

$ sudo swapoff -a

- port 확인

master node에 6443, 8080 port 가 사용중인지 확인합니다. 사용 중인 서비스가 없어야 합니다.

쿠버네티스 API 서버는 2개의 포트에서 HTTP를 서비스합니다.

- 8080 port : 스트 및 부트스트랩을 하기 위한 것이며 마스터 노드의 다른 구성요소 (스케줄러, 컨트롤러 매니저)가 API와 통신

- 6443 port : TLS를 사용

telnet 10.10.1.15(예시, master node IP Address) 6443

 

- 방화벽 open(서버 방화벽 disable)

방화벽이 설정을 확인한 다음 방화벽이 enable되어 있으면 방화벽을 disable 합니다. 

## 방화벽 설정 확인
sudo ufw status

## 방화벽 disable
sudo ufw disable

 

 

3) kubectl, kubeadm, kubelet 설치

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl

sudo apt-mark hold kubelet kubeadm kubectl

 

2. master node  설치

1) control plane 구성

control plane은 master node에만 구성합니다.(multi master 구성시에는 multi master 에 구성)

contron plane을 구성한다는 것은 kube-apiserver, kube-controller-manager, kube-scheduler, etcd, coreDns 를 설치하는 것입니다. 사용자가 kubeadm init 명령어만 수행하면 kubeadm 이 알아서 구성을 해줍니다.

kubeadm init 명령어로 control plane 을 구성합니다. 명령어 수행 제일 하단에 아래와 같이 kubeadm join 으로 시작하는 정보가 표시됩니다. 이 명령어는 나중에 worker node 에서 수행하여 cluster를 구성하는 명령어입니다. 별도로 저장해 놓습니다.

$ kubeadm init

## 수행결과
...
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/
...
kubeadm join 10.10.1.20:6443 --token x8g6zc.1yb94eh1u1940rrj \
	--discovery-token-ca-cert-hash sha256:996f5ea00339533897cd991fb005349eeb366af000b13c8458f9743d5ada230c

 

root와 일반 user가 쿠버네티스 명령어를 사용할 수 있도록 환경 설정(master node에 설정)을 합니다.

 

root 유저로 kubectl 명령어를 수행하려면 root 유저로 아래를 설정합니다.

export KUBECONFIG=/etc/kubernetes/admin.conf

 

일반 유저로 kubectl 명령어를 수행하기 위해 일반 유저로 아래를 설정합니다.

mkdir -p $HOME/.kube

## admin.conf 파일은 kubelet 설치 시 생성
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

참고) 쿠버네티스 클러스터 구성 시 pod 의 네트워크 대역을 설정할 수 있습니다.

kubeadm init --pod-network-cidr=10.244.0.0/16;

 

2) CNI 설치(master node에 설정)

CNI(Container Network Interface)를 설치하여 Pod 간 통신을 할 수 있도록 합니다.

pod 네트워크 애드온 종류는 많습니다(calico, canal, flannel, romana, weave net 등).

원하는 네트워크 애드온을 마스터 노드에 설치합니다.

본 문서에서는 weave network add on 을 설치합니다. 

Weave Net을 설치하기 전에 TCP 6783 및 UDP 6783/6784 포트가 방화벽에 의해 차단되지 않았는지 확인해야 합니다.

아래 명령어로 weave network add-on을 설치합니다.

<weabenet 설치>

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

## 실행결과
serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.apps/weave-net created

2022.10.20 일 기준으로 kubectl 버전에 따라 위의 명령어가 수행되지 않을 경우, 아래 명령어를 수행한다

kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

<calico 설치>

1. operator 설치

kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

2. calico 설정 파일 다운로드

curl https://raw.githubusercontent.com/projectcalico/calico/v3.24.3/manifests/custom-resources.yaml -O

3. calico 설치

kubectl create -f custom-resources.yaml

 

<flannel 설치>

주의할 점 : master node에서 컨트롤 플레인 설정 시 반드시 --pod-network-cidr=10.244.0.0/16 옵션으로 수행해야 한다

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

아래 명령어로 flannel CNS를 설치한다.

kubectl apply -f https://github.com/coreos/flannel/raw/master/Documentation/kube-flannel.yml

 

3. worker node  Join

worker node를 master node에  join 시킵니다.

master node 에서 수행한 kubeadm init 명령어의 실행 결과창에서 보여진 kubeadm join으로 시작되는 부분을 실행해 줍니다.

kubeadm join 10.10.1.15:6443 --token 2gcmlw.zfvrc2b42j3q30zk \
	--discovery-token-ca-cert-hash sha256:aeb530a1ee53667a603d53d9d9abe12a32009b9f432b0fbca40fa1116c1fcc46

 

4. 쿠버네티스 구성 확인

마스터 노드(control-plane 노드)에서 kubectl get nodes 로 node 정보를 확인합니다. 아래와 같이 조회되면 정상입니다.

STATUS 가 모두 Ready 상태여야 합니다.

$ kubectl get nodes
NAME       STATUS   ROLES                  AGE     VERSION
master     Ready    control-plane,master   10h     v1.23.6
worker-1   Ready    <none>                 9h      v1.23.6
worker-2   Ready    <none>                 2m40s   v1.23.6

 

5.  kubectl 예제

kubectl get 명령어로 클러스터를 구성하고 있는 node 정보를 볼 수 있습니다.

## node 정보조회
$ kubectl get nodes

## node 정보 상세조회
$ kubectl get nodes -o wide

컨테이너를 실행하면서 kubectl 명령어 사용하기

아래 명령어는 nginx 최신 버전의 이미지로 webserver 라는 이름의 pod를 생성하고 실행하라는 내용입니다.

$ kubectl run webserver --image=nginx:latest --port 80
pod/webserver created

생성된 pod를 확인합니다. 아래 내용을 보면 현재 상태가 container creating 인 것을 확인할 수 있습니다. pod가 정상적으로 생성완료되면 running으로  상태가 변경됩니다. 현재 진행되는 상태를 보려면 kubectl describe pods 명령어를 수행합니다.

$ kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
webserver   0/1     ContainerCreating   0          23s

## pods 정보 확인
$ kubectl get pods webserver -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP          NODE     NOMINATED NODE   READINESS GATES
webserver   1/1     Running   0          49m   10.44.0.1   node-1   <none>           <none>

## pods 상태 상세확인
$ kubectl describe pods webserver
## 실행결과
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  57s   default-scheduler  Successfully assigned default/webserver to node-1
  Normal  Pulling    56s   kubelet            Pulling image "nginx:latest"
  Normal  Pulled     48s   kubelet            Successfully pulled image "nginx:latest" in 8.496066344s
  Normal  Created    48s   kubelet            Created container webserver
  Normal  Started    48s   kubelet            Started container webserver

node-1에서 10.44.0.1 IP로 nginx 웹서버가 작동하고 있는 것을 확인할 수 있습니다.

 

 

컨테이너 확인하기

curl 명령어로 위에서 생성한 nginx pod 가 정상 동작하는지 확인해 봅니다.(참고. elinks(이링크스)라는 유닉스 기반 운영 체제를 위한 텍스트 기반 콘솔 웹 브라우저로 웹 페이지를 확인할 수 있습니다.)

curl 10.44.0.1

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
....

 

kubectl create 명령어

파일 또는 표준 입력에서 리소스를 생성합니다. JSON and YAML 형식의 파일을 사용할 수 있습니다.

 

usage:
  kubectl create deployment NAME --image=image -- [COMMAND] [args...] [options]

 

kubectl create deployment mainui --image=httpd:latest --replicas=3

생성된 pod를 확인합니다.

1) kubectl get deployment.apps 명령어로 확인

kubectl get deployments.apps 
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
mainui   3/3     3            3           46s

2) kubectl get pods 명령어로 확인

$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
mainui-7bdb5f79fb-4qvhc   1/1     Running   0          3m29s
mainui-7bdb5f79fb-btblc   1/1     Running   0          3m29s
mainui-7bdb5f79fb-nrdv5   1/1     Running   0          3m29s
webserver                 1/1     Running   0          128m

 

배포한 웹서버의 웹페이지 변경하기

kubectl exec  명령어로 위에서 생성한 webserver pod의 웹페이지를 변경해 봅니다.

kubectl exec  명령어는 동작중인 컨테이너의 셸에 접근할 수 있도록 해주는 명령어입니다.

kubectl exec --stdin --tty webserver -- /bin/bash
또는
kubectl exec -it webserver -- /bin/bash

## 실행결과(컨테이너에 접속됨)
root@webserver:/#

 

nginx 웹페이지는 /usr/share/nginx/html 디렉토리에 있습니다. index.html 파일이 웹서버의 첫 웹페이지입니다.이 웹페이지를 원하는 내용으로 변경하고 curl이나 elinks 로 변경된 내용을 확인합니다.

# cat > index.html
NGINX 웹서버입니다.
ctrl + D 를 클릭하여 저장합니다.
# exit

$ curl 10.44.0.1
NGINX 웹서버입니다.

 

nginx log도 확인해 봅니다. nginx log는 컨테이너의 /var/log/nginx 밑에 access.log, error.log 파일입니다.

$ kubectl logs webserver

...
10.32.0.1 - - [05/May/2022:16:27:14 +0000] "GET / HTTP/1.1" 200 615 "-" "ELinks/0.13.1 (textmode; Linux 5.13.0-1024-gcp x86_64; 153x16-2)" "-"
10.44.0.0 - - [05/May/2022:18:15:45 +0000] "GET / HTTP/1.1" 200 29 "-" "curl/7.68.0" "-"
10.44.0.1 - - [05/May/2022:18:16:20 +0000] "GET / HTTP/1.1" 200 29 "-" "curl/7.74.0" "-"

이제 외부에서 pod에 접속할 수 있도록 port-forward 명령어를 사용합니다.

아래 명령어는 외부에서 8080으로 접속하면 pod의 80 port로 forwarding 하는 예시입니다.

$ kubectl port-forward --address=0.0.0.0 webserver 8080:80

다른 서버에서 curl 명령어를 사용하여 웹서버 페이지를 호출해 봅니다.

$ curl http://10.10.1.35:8080

NGINX 웹서버입니다

위에서 생성한 mainui pod의 개수를 3개에서 kubectl edit 명령어로 변경해 봅니다.

아래 명령어를 수행하면 mainui pod에 대한 설정값을 vi 에디터로 불러옵니다. 여기서 변경하고자 하는 값을 변경하면 됩니다. 본 문서에서는 replicas를 3개에서 5개로 변경해 보겠습니다. 변경 후 :wq 로 저장하고 vi 에디터를 빠져나옵니다.

kubectl edit deployments.app mainui

....
spec:
  progressDeadlineSeconds: 600
  replicas: 5
...

pod 갯수가 변경되었는지 확인합니다. 아래와 같이 mainui pod가 5개로 변경된 것을 볼 수 있습니다.

kubectl get pods

## 실행결과
$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
mainui-7bdb5f79fb-4qvhc   1/1     Running   0          76m
mainui-7bdb5f79fb-8t9r9   1/1     Running   0          2m23s
mainui-7bdb5f79fb-btblc   1/1     Running   0          76m
mainui-7bdb5f79fb-nrdv5   1/1     Running   0          76m
mainui-7bdb5f79fb-q6nlg   1/1     Running   0          61s
webserver                 1/1     Running   0          3h20m

 

pod 생성할 내용을 파일로 생성해 봅니다.

--dry-run 플래그를 사용하여 실제로 제출하지 않고 클러스터로 보낼 오브젝트를 미리 볼 수 있습니다.

리다이텍션으로 파일로 저장할 수도 있습니다.

kubectl run webserver --image=nginx --port 80 --dry-run=client -o yaml > webser.yaml

yaml 파일로 pod를 생성합니다. 기존에 생성한 이름과 동일한 pod를 생성하므로 기존 pod를 삭제한 후 실행합니다.

## 기존 webserver pod 삭제
$ kubectl delete pod webserver

## yaml 파일로 pod 생성
$ kubectl create -f webserver.yaml

## 생성된 pod 확인
$ kubectl get pods

 

[참고] kubectl create vs apply 

 

kubectl create
kubectl create는 명령형 관리를 위한 것입니다. 이 접근 방식에서는 생성, 교체 또는 삭제하려는 항목을 Kubernetes API에 알립니다. 간단히 말해서 create는 새 객체를 생성합니다. 리소스가 이미 있는 경우 오류가 발생합니다.

 

kubectl apply

kubectl apply는 다른 변경 사항을 개체에 적용하더라도 라이브 개체에 적용했을 수 있는 변경 사항(즉, 규모를 통해)이 "유지 관리"되는 선언적 관리 접근 방식의 일부입니다.
apply는 우리가 필요로 하는 것을 정의함으로써 기존 객체를 점진적으로 변경합니다. 리소스가 이미 있는 경우 오류가 발생하지 않습니다.

 

pod 삭제

예제) kubectl delete pods <pod> : <pod> 부분에 삭제할 pod 이름을 입력합니다.

kubectl delete pods webserver

 

 

 

 

'쿠버네티스' 카테고리의 다른 글

쿠버네티스 - play with k8s  (0) 2022.10.20
CKA 자격증 취득하기 - 시험예상 문제  (0) 2022.06.09
쿠버네티스 보충  (0) 2022.06.08
CKA 자격증 취득하기 #2  (0) 2022.05.23
CKA 자격증 취득하기 #1  (0) 2022.05.18

How to Set or Change the Time Zone in Linux

 

현재 TimeZone 확인

timedatectl은 시스템의 시간과 날짜를 보고 변경할 수 있는 명령어입니다. 모든 최신 시스템 기반 Linux 시스템에서 사용할 수 있습니다.

현재 시간대를 보려면 옵션이나 인수 없이 timedatectl 명령을 실행합니다.

 

timedatectl
               Local time: Fri 2022-06-24 05:50:38 UTC
           Universal time: Fri 2022-06-24 05:50:38 UTC
                 RTC time: Fri 2022-06-24 05:50:38
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

 

위의 출력은 시스템의 시간대가 UTC로 설정되었음을 보여줍니다.
시스템 시간대는 /etc/localtime 파일을 /usr/share/zoneinfo 디렉토리의 바이너리 timezone 에 심볼릭 링크로 구성됩니다.

 

시간대를 확인하는 또 다른 방법은 ls 명령을 사용하여 심볼릭 링크가 가리키는 경로를 보는 것입니다.

ls -l /etc/localtime
lrwxrwxrwx 1 root root 27 Dec  3 16:29 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC

Time Zone 변경

시간대를 변경하기 전에 사용하려는 시간대 이름을 찾아야 합니다. 표준 시간대 명명 규칙은 일반적으로 "지역/도시" 형식을 사용합니다.
사용 가능한 모든 시간대를 보려면 timedatectl 명령을 사용하거나 /usr/share/zoneinfo 디렉토리에 있는 파일을 나열합니다.

timedatectl list-timezones

...
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
...

현재 위치에 맞는 시간대를 확인한 후 루트 또는 sudo 로 다음 명령을 실행합니다.

sudo timedatectl set-timezone <your_time_zone>

예를 들어 시스템의 시간대를 Asia/Seoul 로 변경하려면 다음을 입력합니다.

sudo timedatectl set-timezone Asia/Seoul

변경 사항을 확인하려면 timedatectl 명령을 다시 호출합니다.

timedatectl

               Local time: Fri 2022-06-24 15:00:17 KST
           Universal time: Fri 2022-06-24 06:00:17 UTC
                 RTC time: Fri 2022-06-24 06:00:17
                Time zone: Asia/Seoul (KST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

 

이전 Linux 배포판을 실행 중이고 시스템에 timedatectl 유틸리티가 없는 경우 /etc/localtime을 /usr/share/zoneinfo 디렉토리의 시간대에 심볼릭 링크하여 시간대를 변경할 수 있습니다.
현재 심볼릭 링크 또는 파일을 제거합니다.

sudo rm -rf /etc/localtime

구성하려는 시간대를 식별하고 symlink를 생성합니다.

sudo ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime

 

/etc/localtime 파일을 나열하거나 date 명령어로 변경된 시간을 확인합니다.

date

 

 

+ Recent posts