HyperText Transfer Protocol 은 인터넷 미디어를 전송하기 위한 규약이다. 인터넷 미디어라는 단어를 쓰기는 했지만, 요즘에는 인터넷을 통해서 못하는게 없을 정도로 인터넷 미디어를 규정하는 매체의 경계는 없다. 따라서 “인터넷 미디어를 전송하기 위한 규약”은 구시대적인 정의이며 차라리 “인터넷을 이용한 웹을 사용할 경우에 쓰이게되는 규약” 정도가 더 잘 맞는듯 하다. HyperText 는 텍스트를 가지는 노드사이에 지역적인 링크(이걸 HyperLink라 한다)를 사용하는 구조적 텍스트를 말한다. 쉽게 말해서 웹사이트에서 링크를 클릭하면서 텍스트를 불러오는 텍스트 구조를 말하는 것이다. History 1989년 CERN (유럽 입자 물리학 연구소) 에 근무하던 […]
[번역] 바쁜 리눅스 서버에서 TCP TIME-WAIT 상태 대처하기.
이 문서는 원작자의 동의를 얻어 다음이 포스트를 발 번역한 것 입니다. Coping with the TCP TIME-WAIT state on busy Linux servers 그리고 이 글의 라이센스는 “CC BY-NC-SA 3.0” 입니다. 글 아래의 라이센스는 이 글에서는 해당되지 않음을 알려 드립니다. 다시 한번 원작자 Vincent Bernat 씨에게 감사 합니다. net.ipv4.tcp_tw_recycle 를 활성화하지 말라! 리눅스 커널 문서는 net.ipv4.tcp_tw_recycle 이 무엇인지에 대해서 별다른 도움이 안된다. TIME-WAIT 소켓의 빠른 재사용을 활성화. 기본값은 0이다. 기술적인 전문가의 충고나 요구없이 함부로 바꿔서는 안된다. 이와 비슷한, net.ipv4.tcp_tw_reuse 는 좀더 문서화되었지만 […]
[번역] MySQL 5.7.6 릴리즈. 큰 변화에 준비하자.
이 글은 “MySQL 5.7.6 is out. Be prepared for big changes” 를 원작자의 허락을 받아 번역한 것입니다. 원본은 아래의 주소에 있습니다. 번역을 허락해준 Giuseppe Maxia 씨에게 감사 합니다. MySQL 5.7.6 is out. Be prepared for big changes 오늘 오라클(Oracle)이 MySQL 5.7.6 마일스톤 16을 릴리즈(Release) 했다. 이것으로 MysQL 5.7 은 개발에 2년이 넘게 소요됐다. MySQL 5.6과 비교해 바뀐점은 아주 넓다. 주요한 팀(개발 팀)의 노력은 이전 릴리즈와 비교해 2배에서 3배의 성능 향상을 가지는 , MySQL 의 동작,스피드에 포커스를 맞춰왔다. 무엇이 새로운지에 대한 전체 […]
리눅스 시스템 자원 제한.
아주 접속이 많은 웹 서버를 운영하던중에 다음과 같은 종류의 메시지를 접하는 경우가 종종 있다.
|
1 |
Too many open files (24) |
너무나 많은 파일을 열었다는 건데, 도대체 무슨 파일을 열었다는건지 서비스하는 웹 페이지의 파일 개수도 많지도 않은데 말이다. 이 문서는 이러한 의문을 가지는 사람들 위한 것이다. 모든게 파일! 리눅스 시스템은 모든것이 파일이다. 장치도 파일이다. 그 유명한 /dev/ 디렉토리에 있는 팡리들이 바로 장치들이다. 저 파일들에게 cat 명령어로 데이터를 던져주면 그것을 알아먹는 장치는 동작하게 된다. 또, 리눅스에서 프로그램의 실행은 혼자 동작하는 것이 아니다. C 프로그램을 해본사람이라면 라이브러리(Library) 개념을 […]
Nginx KeepAlive
Nginx 에서 KeepAlive 관련된 설정은 다음과 같이 세가지이다. keepalive_disable keepalive_timeout keepalive_requests 먼저, Keepalive 는 HTTP 와 TCP 상에서 구현되어 있다. HTTP 의 경우에는 1.0 버전과 1.1 버전이 존재하는데, 1.0 버전에서는 KeepAlive 는 존재하지 않으며 1.1 에서는 연결시에 기본으로 KeepAlive 가 활성화 된다. HTTP 는 “Connetionless” 방법을 취한다. 웹 컨텐츠를 전송 받기 위해서 서버에 연결을 한 후에 데이터를 전송받는다. 그리고는 연결을 바로 끊게 된다. 하지만 웹이라는게 HTML, Javascript, CSS, Image 파일등으로 수백개로 이루어진 상태에서 수백의 컨텐츠를 전송하기위해서 연결을 수백번을 한다면 비 […]
[번역]레디스 슬레이브에서 “놓쳐버린” 키들.
이 문서는 다음의 글을 번역한 것입니다. “Missing” Keys on Redis Slaves 레디스 슬레이브에서 “놓쳐버린” 키들. 만약 당신이 레디스(Redis)에서 만료중인 키를(expiring key)(“임시적인 키”로 알려진) 사용하고 있다면, 당신은 레디스 마스터에서 새로운 슬레이브(Slave)를 붙였을때에 놀랄 수도 있습니다. 슬레이브에서 키 갯수(key count)가 마스터에서 키 갯수보다 약 25%정도 낮을 것입니다. 이것은 임시적인 키(volatile key)가 아주 많다면 특별하게도 정상적인 것입니다. 레디스 슬레이브가 키를 놓쳐버린 걸까? 단순하게 데이터를 잃어버린 걸까? 결론부터 말하자면 “아니오” 입니다. 그러나, 왜그런지 이해하길 희망하면서, 레디스 슬레이브가 어떠한 데이터도 잃어버리지도 않았는데도 더 적은 키 […]
Redis 운영에 필요한 잡지식들.
Redis 는 In memory 기반으로 동작하기 때문에 메모리 관리가 매우 중요한데, 먼저 리눅스에 메모리 관리를 Redis 운영에 적합하도록 설정하는 것이 좋다. 먼저 Redis 는 Swap 을 사용하지 않고 물리 메모리 내에서만 운영하는 환경이다.
|
1 2 3 4 5 |
vm.overcommit=2 vm.overcommit_ratio=99 vm.swappiness=0 echo never > /sys/kernel/mm/transparent_hugepage/enabled |
가상 메모리 overcommit 에 대해서 2 로 설정하는 것이 좋다. 2로 설정하게 되면 리눅스가 사용가능한 메모리는 다음과 같이 계산한다.
|
1 |
swap + (physical memory * overcommit_ratio) |
예를들어 32GB 물리 메모리를 가지고 있고 overcommit_ratio 가 50%라면 16GB 물리 메모리만 사용하게 된다. 그래서 overcommit_ratio 를 99% 로 설정을하면 모든 메모리를 사용하게 된다. swappiness 는 […]
Python redis 테스트 스크립트.
랜덤으로 키를 생성해서 값을 넣도록 만든 Python redis 테스트 스크립트.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/usr/bin/env python from multiprocessing import Process import redis import random import string import time def id_generator(size=6, chars=string.ascii_uppercase + string.digits): return ''.join(random.choice(chars) for x in range(size)) data = id_generator(12, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()") def g(idx): r_server = redis.Redis('localhost') for i in xrange(idx * 1024 * 1024 * 2, (idx+1)*1024*1024 * 2): key = 'PR%s'%(id_generator(random.randrange(6,15), "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()")) if random.randrange(1,100) > 70: r_server.setex(key, id_generator(random.randrange(128,1024), "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()"),random.randrange(1,350)) print "expire key: %s" % key else: r_server.set(key, id_generator(random.randrange(128,1024), "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()")) print "permanent key: %s" % key time.sleep(0.2) if __name__ == '__main__': pids = [] for i in xrange(80): p = Process(target=g, args=(i,)) pids.append(p) p.start() for pid in pids: pid.join() |
tomcat jmx 소스
JMX 소스
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import java.io.Console; public class check_jmx { public static final char ESC = 27; public static void main(String[] args) { // TODO Auto-generated method stub try { // Create an RMI connector client and // connect it to the RMI connector server // JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); ObjectName tomcatThreadPoolObh = new ObjectName("Catalina:type=Executor,name=tomcatThreadPool"); Object activeCnt = mbsc.getAttribute(tomcatThreadPoolObh, "activeCount"); ObjectName memoryObh = new ObjectName("java.lang:type=Memory"); CompositeData memoryRes = (CompositeData) mbsc.getAttribute(memoryObh, "HeapMemoryUsage"); Console c = System.console(); if (c == null) { System.err.println("no console"); System.exit(1); } // clear screen only the first time c.writer().print(ESC + "[2J"); c.flush(); Thread.sleep(200); for (int i = 0; i < 100000; ++i) { // reposition the cursor to 1|1 c.writer().print(ESC + "[1;1H"); c.flush(); //c.writer().println("hello " + i); c.writer().println("activeCount = " + activeCnt); c.writer().println("HeapMemoryUsage committed = " + memoryRes.get("committed")); c.writer().println("HeapMemoryUsage init = " + memoryRes.get("init")); c.writer().println("HeapMemoryUsage max = " + memoryRes.get("max")); c.writer().println("HeapMemoryUsage used = " + memoryRes.get("used")); c.flush(); Thread.sleep(5000); } /* echo("activeCount = " + activeCnt); echo("HeapMemoryUsage committed = " + memoryRes.get("committed")); echo("HeapMemoryUsage init = " + memoryRes.get("init")); echo("HeapMemoryUsage max = " + memoryRes.get("max")); echo("HeapMemoryUsage used = " + memoryRes.get("used")); */ jmxc.close(); } catch (Exception e) { e.printStackTrace(); } } private static void echo(String msg) { System.out.println(msg); } } |
Redis 설치하기
Redis 는 Key-Value 로 데이터를 저장하는 NoSQL 서버 입니다. In Memory 기반으로 동작하기 때문에 빠른 응답속도를 보입니다. 이 문서는 Redis 설치에 관한 문서 입니다. 다운로드
|
1 |
wget http://download.redis.io/releases/redis-2.8.19.tar.gz |
의존성 패키지 설치 CentOS 의 경우에는 다음과 같이 설치를 해줍니다.
|
1 2 3 |
yum install gcc.x86_64 gcc-c++.x86_64 wget.x86_64 bzip2-devel.x86_64 pkgconfig.x86_64 openssl-devel.x86_64 make.x86_64 man.x86_64 nasm.x86_64 gmp.x86_64 gdbm-devel.x86_64 readline-devel.x86_64 compat-readline43.x86_64 ncurses-devel.x86_64 db4-devel.x86_64 automake* autoconf* pcre-devel.x86_64 -y yum install tcl-devel.x86_64 tcl.x86_64 |
Ubuntu 의 경우에는 다음과 같이 설치를 해줍니다.
|
1 2 3 |
sudo apt-get install build-essential sudo apt-get install tcl8.5 |
컴파일
|
1 |
make |
설치 설치는 PREFIX 를 인자로 줘서 설치 디렉토리 위치를 지정해줄 수 있습니다.
|
1 |
make install PREFIX=/usr/local/redis |
Redis 의 설치는 오로지 실행파일들만 복사해 줍니다. 설정 Redis 는 설치 후에 각종 설정을 할 수 있도록 스크립트를 지원 […]