๋น ๋ฐ์ดํฐ๋ก ์์ ํ ๋ ์ฑ๋ฅ์ ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ
์ฌ์ด์ฆ๊ฐ ํฐ ๋ฐ์ดํฐ๋ก ์์ ํ ๋ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ง์ ์์ ๊ณ์ฐ์ด ํ์ํฉ๋๋ค. ์ฝ๋๊ฐ ๋๋ค๊ฐ ์ค๊ฐ์ ์๋ฌ๊ฐ ๋์ ๋ฉ์ถ๋ค๋๊ฐ ํน์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋ฐ ์ค๋ ์๊ฐ์ ์๋นํ ๋ ๋ฐ๋ ์คํธ๋ ์ค๋... ๋จธ์ ๋ฌ๋์ด๋ ๋ฅ๋ฌ๋ ๊ด๋ จ ๋ชจ๋ธ๋ง ์์ ์ ํ ๋ ๋ฐ์ดํฐ๋์ด GB ๋จ์๋ผ๋ฉด ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๊ฒ ๋ฉ๋๋ค.
์ด์ฒ๋ผ ๋ณต์กํ๊ณ ์ฐ์ฐ์ด ๋ง์ด ํ์ํ ์์ ์ ์ฑ๋ฅ ์๋๋ฅผ ํฅ์์ํค๋ ๋ฐฉ๋ฒ์๋ ํฌ๊ฒ ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค:
1. Vertical Scaling (์์ง์ ์ค์ผ์ผ๋ง)
Vertical Scaling์ ๋จ์ํ๊ฒ ์ปดํจํ ํ์๋ฅผ ๋๋ฆฌ๋ ๊ฒ์ ๋๋ค. ๋ ์ข์ ๊ทธ๋ํฝ ์นด๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ CPU์ ์ฑ๋ฅ์ ๋์ด๋ ๋ฑ ๋ ๋์ ํ๋์จ์ด๋ฅผ ๊ตฌ๋งคํ๋ ๋ฐฉ์์ผ๋ก ์์ ์๋๋ฅผ ํฅ์ ์ํต๋๋ค. ์์ ๊ฑฐ ํ ๋๋ก ์ด์ฟ์ง์ ๋๋ฅด๋ ๋์ ์ ์ฉ๋ฌ ํ๋๋ฅผ ๋ถ๋ฌ์ ์ง์ ์ฎ๊ธฐ๋ ๋ฐฉ์์ ๋๋ค.
2. Horizontal Scaling (์ํ์ ์ค์ผ์ผ๋ง)
Horizontal Scaling์ ์ญ์์ผ๋ฐ์ ๋ฐฉ์์ผ๋ก ๋ ๋ง์ ์ปดํจํ ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์์ ์ฑ๋ฅ์ ๋์ ๋๋ค. ์ด์ฟ์ง์ ๋๋ ์ ์ฌ๋ฌ ๋์ ์์ ๊ฑฐ๋ก ์์ ์ ํ๋ ์ ์ด์ฃ
๋น ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ Vertical Scaling์ ์ปดํจํ ์์์ ํฌ์๋ฅผ ๋ง์ด ํ ์ ์๋ ์ฌ๊ฑด์ด ๋ ๊ฒฝ์ฐ์ ํจ์จ์ ์ ๋๋ค. ํ์ง๋ง ๊ธ์ ์ ์ธ ๋ถ๋ถ์ ๊ณ ๋ คํด์ผํ๊ธฐ ๋๋ฌธ์ ํญ์ ์ ๋ต์ด ๋ ์ ์์ต๋๋ค. ์ด๋ฒ ํฌ์คํธ์์๋ Horizontal Scaling ๋ฐฉ์์ธ ๋ฉํฐํ๋ก์ธ์ฑ์ ํ์ฉํ์ฌ Python์ ์์ ์๋๋ฅผ ๊ฐ์ ์ํค๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
๋ฉํฐํ๋ก์ธ์ฑ (Multiprocessing)
๋๋ถ๋ถ์ ์ปดํจํฐ๋ค์ ๋ฉํฐ์ฝ์ด CPU๊ฐ ํ์ฌ๋์ด ์์ต๋๋ค. ๊ฐ๋จํ๊ฒ ์ค๋ช ์ ํ์๋ฉด CPU์์ ์ฌ๋ฌ ๋์ ์์ ๊ฑฐ๊ฐ ์๋ค๋ ๋ป์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก Python์ผ๋ก ์ฝ๋๋ฅผ ๋๋ฆฌ๋ฉด ํ๊ฐ์ ์ฝ์ด๊ฐ ๊ทธ ์์ ์ ์ํํ๊ฒ ๋ฉ๋๋ค. ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ๋ฌ๊ฐ์ ์ฝ์ด์๊ฒ ์์ ์ ๊ท ๋ฑํ๊ฒ ๋๋ ์ค์ ์์ ์ฒ๋ฆฌ ์๋๋ฅผ ๋น ๋ฅด๊ฒ ํ๋ ํ์์ ๋๋ค.
์ ๊ฐ ๋ํ์์ด๋ ์์ , ์๋์ ์งค์ด ํฌ๊ฒ ์ ํํ์๋ ๊ฒ์ผ๋ก ๊ธฐ์ตํฉ๋๋ค. ๋น์ ๊ฐ ์๋ ์ฐฐ๋ก์ด๋ผ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
Python์ผ๋ก ๋ฉํฐํ๋ก์ธ์ฑ (Multiprocessing)
Python์๋ ์์ฒด์ ์ผ๋ก ๋ด์ฅ๋ ํจ์ multiprocessing
์ด ์์ต๋๋ค. pip๋ฅผ ์ฌ์ฉํด์ ๋ฐ๋ก ์ค์น๊ฐ ํ์์๋ค๋ ์๋ฏธ์
๋๋ค. ์ฐ์ ๋ฉํฐํ๋ก์ธ์ฑ ์์ด 1๋ถํฐ 2000๊น์ง์ ํฉํ ๋ฆฌ์ผ์ ๊ณ์ฐํ๋ ์์
์ ํด๋ณด๊ฒ ์ต๋๋ค.
[Input]
import time
# starting time
start = time.time()
# save the factorial results here
s_results = []
# add all integers from 1 to 1_000_000
def factorial(i):
x = 1
for k in range(1,i+1):
x = x*k
results.append(x)
# number of test cases
cases = [x for x in range(0,2001)]
for c in cases:
factorial(c)
print("%s seconds" % (time.time()-start))
[Output]
> 0.5778999328613281 seconds
์ด์ ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ์ฉํด์ ๊ณ์ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
[Input]
import multiprocessing as mp
import time
# starting time
start = time.time()
# save the factorial results here
p_results = []
# calculate factorial of a number
def factorial(i):
x = 1
for k in range(1,i+1):
x = x*k
p_results.append(x)
# factorials from 1 to 2000
cases = [x for x in range(1,2001)]
######################
### ๋ฉํฐํ๋ก์ธ์ฑ ###
pool = mp.Pool(processes=5) # ์ฌ์ฉํ๊ณ ์ถ์ ์ฝ์ด ํ๋ก์ธ์์ ์
pool.map(factorial, cases)
pool.close()
pool.join()
######################
print("%s seconds" % (time.time()-start))
[Output]
0.222374095917 seconds
์์ ์๋๊ฐ 2๋ฐฐ ์ด์์ผ๋ก ํ์คํ ๋นจ๋ผ์ก์ต๋๋ค.
!! ์ฃผ์์ !!
ํ์ง๋ง ๋ฉํฐํ๋ก์ธ์ฑ์ ์ฌ์ฉํ๋ค๊ณ ํด์ ํญ์ ์์ ์๋๊ฐ ๋นจ๋ผ์ง๋ ๊ฒ์ ์๋๋๋ค. ๋ฉํฐํ๋ก์ธ์ฑ์ ํ๊ฒ ๋ ๊ฒฝ์ฐ, ์์ ์ ๋๋ ์ ๊ฐ ํ๋ก์ธ์์ ํ ๋นํ๋ ์๊ฐ์ด ์ถ๊ฐ๊ฐ ๋ฉ๋๋ค. ์ด์ฟ์ง์ด ๋ฌ๋ ๋ฐ์ค 1๊ฐ ์ธ๋ฐ, ์ฌ๋ฌ ๋์ ์์ ๊ฑฐ๋ก ๋๋ฅด๊ธฐ ์ํด์ 4๋์ ๋ฐ์ค๋ก ๋๋๋ค๊ณ ์๊ฐํด๋ณด์ธ์. ์ ์๊ฐ๋ญ๋น์ ๋๋ค.
์ดํด๊ฐ ์๋์ ๋ค๋ฉด ์๋์ ์์๋ฅผ ๋ณด์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค:
[Input]
import multiprocessing as mp
import seaborn as sns
import pandas as pd
import time
# calculate factorial of a number
def factorial(i):
x = 1
for k in range(1,i+1):
x = x*k
# measuring computation time for seq and parallel
seq_times = []
prl_times = []
for i in range(101,2501):
cases = [x for x in range(1,i)]
# Sequential ๋ฉํฐํ๋ก์ธ์ฑ X
# starting time
seq_start = time.time()
for c in cases:
factorial(c)
seq_times.append(time.time()-seq_start)
# Parallel ๋ฉํฐํ๋ก์ธ์ฑ O
prl_start = time.time()
pool = mp.Pool(processes=5) # Number of processes that you want to use
pool.map(factorial, cases)
pool.close()
pool.join()
prl_times.append(time.time()-prl_start)
fac = [i for i in range(101,2501)]
df = pd.DataFrame(data={"upper limit":fac,
"sequential":seq_times,
"parallel":prl_times})
df = df.melt(id_vars="upper limit",value_name="time",var_name="processing type")
sns.set(rc={'figure.figsize':(15,8)})
ax = sns.lineplot(x=df["upper limit"], y=df["time"], hue=df["processing type"])
ax.axes.set_title("Sequential vs Parallel processing time of factorial() function",fontsize=18)
ax.set_xlabel("Upperbound of calculated factorials",fontsize=15)
ax.set_ylabel("Time (sec)",fontsize=15)
[Output]
1๋ถํฐ 1100 ์ด์์ ํฉํ ๋ฆฌ์ผ์ ๊ณ์ฐํ ๋ ๋ฉํฐํ๋ก์ธ์ฑ์ด ๋ ๋น ๋ฅธ ์์ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ํ์ธํ์ค ์ ์์ต๋๋ค. ๊ทธ ์๋ ๋ฒ์์ ์์ ์ ์ ๋ถ ์ด์ฟ์ง ํ ๋ฐ์ค๋ฅผ ๋ค ๋ฐ์ค๋ก ๊ตณ์ด ๋๋ ๋ด๊ธฐ๋๋ฌธ์ ์ค๋๊ฑธ๋ฆฐ๋ค๊ณ ์๊ฐํ์๋ฉด ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ ๋ฆฌํ๊ธฐ
๋น ๋ฐ์ดํฐ ํ๊ฒฝ์์๋ ๋น ๋ฅธ ์์ ์๋๋ฅผ ์ํด ๋ณ๋ ฌ์ฒ๋ฆฌ๊ฐ ํ์์ ์ ๋๋ค. ๋ชจ๋ ์ ํ์ฉํ์ ์ ์นผํดํ์๊ธธ ๋ฐ๋ผ๊ฒ ์ต๋๋ค :)
'๐ป ITยท๊ธฐ์ ยทํต๊ณ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[NLP] ์ ๊ทํํ์์ ํ์ฉํ ์ ์ฒ๋ฆฌ ๋ฐ ๋ฐ์ดํฐ ์ถ์ถ (0) | 2023.01.29 |
---|---|
[์นํฌ๋กค๋ง 2ํ] selenium webdriver๋ฅผ ํ์ฉํ ์ํ ๋ฆฌ์คํธ ํฌ๋กค๋ง (0) | 2023.01.29 |
[API] DALLยทE 2 Python์ผ๋ก ์ฌ์ฉํด๋ณด๊ธฐ (3) | 2023.01.25 |
Python์ผ๋ก ๋ฉ์ผ ๋ณด๋ด๊ธฐ [@gmail] (3) | 2023.01.21 |
[์นํฌ๋กค๋ง 1ํ] requests์ bs4๋ฅผ ํ์ฉํ ๋ ์ํผ ๋ชฉ๋ก ํฌ๋กค๋ง (2) | 2023.01.19 |
๋๊ธ