Clustering 강의 동영상
요즘에 하고 있는 작업이 clustering에 관련된 작업이라서 남겨본다.
나중에 자세히 봐야겠다.
갈수록 대용량처리에 대한 요구가 많아지는듯하다. 결국 가지고 있는 정보를 어떻게 처리를 해야되는가인데 앞으로 해야될 일이 많은 것 같네..
If you get an error like this one on Ubuntu,
error while loading shared libraries: libstdc++-libc6.2-2.so.3:
cannot open shared object file: No such file or directory
it means the library isn’t available and you need to install it. Although the Ubuntu package which contains this library isn’t obvious. You can install it via the following command:
sudo apt-get install libstdc++2.10-glibc2.2
Sometimes it needs to exactly mimic Oracle's ROWNUM where is no possibility to initiate a counter in previous statement by SET @rownum:=0;.
It is still possible in a single SQL.
SELECT @rownum:=@rownum+1 rownum, t.*
FROM (SELECT @rownum:=0) r, mytable t;
지난 두 편의 글에서 mongrel을 재시작하는 방법과 Kill -9 이라는 극약 처방에 대해 적었다.
더 노하우가 쌓이면 어떤 상황에서 mongrel 프로세스가 먹통이 되는지에 대해 다루기로 하고, 이 글의 마지막은 monit을 소개하는 것으로 마치려 한다.
무슨 이유에서건 mongrel 프로세스가 서비스를 할 수 없는 상황에 이르게 된다. 현재는 심증만 있고, 물증이 없는 상태라 완벽한 처방은 하지 못하고 있다. 아무튼 서비스를 하려면 이런 프로세스를 최대한 빨리 발견하고 정상화해야 한다. 즉, 주기적인 모니터링과 자동 복구가 필요한 상황이다. 이를 위한 최적의 툴이 바로 monit이다.
monit은 유닉스 시스템에서 프로세스, 파일, 디렉터리를 감시하고 관리하는 유틸리티이다. monit은 자동 관리 및 복구를 가능하게 하므로, 오류가 발생했을 때 시기 적절한 처방을 내릴 수 있다.
설치 과정은 다른 유닉스 프로그램과 크게 다르지 않기 때문에 생략하자. 그 다음 우리가 할 일은 monit에게 mongrel 프로세스를 감시할 수 있는 방법과 처방전을 미리 알려주는 것이 전부이다. 어렵지 않다.
적당한 위치에 monitrc 파일을 만들고(필자는 ~/.monitrc), 다음처럼 적어준다.
check process mongrel_0 with pidfile <SOME-DIR>/shared/log/mongrel.4000.pid
start program = "mongrel_rake.sh start_0"
stop program = "mongrel_rake.sh stop_0"
if totalmem is greater than 100.0 MB for 5 cycles then restart # eating up memory?
if cpu is greater than 50% for 2 cycles then alert # s an email to admin
if cpu is greater than 80% for 3 cycles then restart # hung process?
if loadavg(5min) greater than 10 for 8 cycles then restart # bad, bad, bad
if 3 restarts within 5 cycles then timeout # something is wrong, call the sys-admin
if failed port 4000 protocol http # check for response
with timeout 10 seconds
then restart
group mongrel
mongrel.4000.pid라는 파일에는 4000번 포트를 이용하는 몽그렐 프로세스의 아이디가 저장된다. 그리고 자원을 너무 많이 사용하면 재시작해준다. 가장 중요한 부분은 맨 마지막에 4000번 포트를 감시하는 부분이다. 10초안에 접속이 되지 않는 경우 먹통이 된 것으로 판단하고 필요한 조치를 취한다. 여기서는 당연히 재시작이다. 재시작은 stop program과 start program을 하나씩 실행해주는 방법이다. 필자는 지난번에 소개한 우아한 재시작 프로그램을 따로 만들어두고, 이 스크립트를 실행하도록 하였다. 이 부분에 그냥 mongrel_rails를 실행하도록 두어도 된다.
이런 방법으로 클러스터링해둔 프로세스를 모두 감시하도록 monitrc 파일을 작성하면 된다. 반복되지만, 해결할 수 있는 방법은 찾지 못했다.
여기에 덧붙여 이런 내용을 monitrc에 추가한다.
set daemon 60
set logfile monit.log
set pidfile monit.pid
set statefile monit.state
set httpd port 9999
use address localhost
allow username:password
60초마다 감시를 하고 필요한 정보(log, pid, state)를 파일로 남기도록 지정한다. 그리고 9999번 포트로 관리툴을 띄운다. 물론 HTTP 인증을 거치도록 설정해둔다.
이 관리툴도 유용한데, 현재 서비스가 잘 이뤄지고 있는지 한 눈에 파악할 수 있는 모니터링 툴이다. 여기서 Stop, Start등 monit 명령어를 수행할 수도 있다.
마지막으로 주의할 점은, 모니터링을 켜두고 몽그렐 클러스터를 재시작하는 경우이다. 재시작은 프로세스를 죽이도 다시 시작한다. 그런데 다시 시작하는 동작이 2번 일어날 수 있다. 물론, 두 번째 프로세스는 이미 포트가 바인드된 상태이므로 큰 문제 없이 실패하겠지만, 그래도 불필요하게 두번 시작하는 것을 막기 위해서라면, 재시작 전에 모니터링을 끄는 것도 방법이다.
monit -g mongrel unmonitor all
-g mongrel을 이용하면 mongrel 그룹으로 지정된 것에 한번에 명령을 내릴 수 있다. 물론, 재시작할 때 mongrel_rails 대신 monit을 이용해도 된다.
monit -g mongrel restart all
이 외에도 monit을 이용해 여러 가지를 감시할 수 있으므로(httpd, ftpd 등), 함께 사용해보면 좋겠다. 더 좋은 설정이 있으면 함께 공유해도 좋을 것 같다.
서비스에 monit을 적용한 이후에, 일단 서비스가 멈추는 일은 없어져서 발 뻗고 잘 수 있게 되었다. 가끔 관리툴에 접속해보면 uptime이 혼자만 짧은 프로세스들이 보이는데, 이 때마다 monit을 설치해두기를 잘했다는 생각이 든다. 이제는 여유롭게 진짜 처방전을 찾아봐야겠다. 뭘까?
관련 링크
Mongrel을 우아하게 재시작하는 법에서 이어서…
mongrel 프로세스를 종료하기 위해 보통 사용하는 명령은 다음과 같다
mongrel_rails stop [options]
문제는 온갖 문제로 특정 프로세스가 TERM 시그널을 받고도 죽지 않는 경우이다. TERM 시그널을 보내고 한참을 기다리면 스스로 사라지기도 하지만, 대부분의 경우 그리 느긋하게 기다릴 수만은 없다. 방법은 kill -9를 하는 것이다. 다행인지 mongrel_rails에는 강제 종료 옵션이 있다.
mongrel_rails -f -w 5
내가 사용하는 방법은 이렇다. TERM을 보내본다. pid 파일이 아직도 있으면(정상적으로 종료되지 않으면) 강제 종료한다.
def stop(i)
pid = "#{APP_HOME}/shared/log/mongrel.400#{i}.pid"
system "mongrel_rails stop -P #{pid} -c #{APP_HOME}/current"
if File.exists?(pid)
system "mongrel_rails stop -P #{pid} -c #{APP_HOME}/current -w 5 -f"
system "rm #{pid}"
end
end
갑자기 ”When Your Mongrel Misbehaves, Kill -9“이라는 명곡이 생각난다. 킬 대시 나인~~.
Creating a popup window is reasonably easy if you just want another browser window of a specified size and you don't care if your visitors swap back and forward between the various browser windows. Where it becomes difficult (if not impossible) is where you want the new window to stay in front of the original window and not allow your visitor to interact with the original window until the new window has closed. We call a window that insists on retaining the focus like this a modal window.
The difficulty is that Javascript does not have a standard way of creating a modal popup window the way it has a standard way to create an ordinary (modeless) window by using window.open().
A number of browsers (for example Netscape 4 or any version of Opera up to and including version 9) do not allow you to make a popup window modal at all. There is simply no command that you can use that will make a window modal in those browsers.
There are two groups of browsers that do allow you to create modal windows and each uses a different method to do so.
Internet Explorer adds an entirely new method to the window object to open a modal window - window.showModalDialog(). If you use that to try to open a modal window then if your visitor is running Internet Explorer then a modal window will be opened. If they are running some other browser then all they will get is a Javascript error.
The Mozilla based browsers (Netscape 6+, Firefox, etc) use a completely different method to declare that the window that is opened should stay in front . They use the normal window.open and just add an extra attribute modal=yes to the list of atributes that define the appearance of the window (unfortunately it still doesn't actually make it modal it just forces it to stay in front which is the best that you can do with these browsers). If you try to use this to try to open a modal window then the window will open in any browser (provided that it hasn't been blocked by a popup blocker) but it will only stay in front if the browser is one of the Mozilla based family. If your visitor is running Netscape 4, any version of Opera, or Internet Explorer etc. then the window will still open it just wont stay in front.
The best that we can do to set up a window that is as modal as we can make it is to combine these two together to create code that will open a modal window in Internet Explorer, keep the window in front in Mozilla based browsers, and which will just open a non-modal window in those browsers that don't support modal windows. Of course we don't want to test which browser that the browser itself claims to be since most Opera browsers are set to report that they are Internet Explorer. Instead we test for support for the showModalDialog method itself to identify those versions of Internet Explorer that support it. Combining the code together gives us the following (with the amendments from an ordinary non-modal window shown in bold).
All that remains is to set up the code to call our modal window function (and of course to allow those without Javascript to have the window open in a separate non-modal browser window as well.
If you want to see what effect that using all of the above code has in your particular browser then click here and if your browser supports modal windows then that is what will open and you will have to select the close link to close that window before being able to return to this page. If your browser doesn't support modal windows then the window will still open but it will not be modal.
Every now and then you need to limit the number of rows MySQL returns, i.e. use the LIMIT clause. Result set pagination is by far the most often usage of LIMIT clause, since you usually want to select only rows you’ll be displaying on certain page.
The problem is that for pagination you also need total number of rows in a result set, so you know how many pages you’ll have. This usually means that you need to execute query two times. First query is for counting total number of rows without LIMIT. Second query is exactly the same as the first, just without LIMIT and it will actually retrieve required data. You would need two queries like these:
SELECT COUNT(*) FROM users WHERE name LIKE 'a%'; SELECT name, email FROM users WHERE name LIKE 'a%' LIMIT 10;
Now, this is not such a big problem when you have small result sets and/or simple queries. But if you have a complex query that joins several tables and takes a while to execute - well, you probably wouldn’t want to execute it twice and waste server resources.
Luckily since MySQL 4.0.0 you can use SQL_CALC_FOUND_ROWS option in your query which will tell MySQL to count total number of rows disregarding LIMIT clause. You still need to execute a second query in order to retrieve row count, but it’s a simple query and not as complex as your query which retrieved the data.
Usage is pretty simple. In you main query you need to add SQL_CALC_FOUND_ROWS option just after SELECT and in second query you need to use FOUND_ROWS() function to get total number of rows. Queries would look like this:
SELECT SQL_CALC_FOUND_ROWS name, email FROM users WHERE name LIKE 'a%' LIMIT 10; SELECT FOUND_ROWS();
The only limitation is that you must call second query immediately after the first one because SQL_CALC_FOUND_ROWS does not save number of rows anywhere.
Although this solution also requires two queries it’s much more faster, as you execute the main query only once.
You can read more about SQL_CALC_FOUND_ROWS and FOUND_ROWS() in MySQL docs.
퍼온 글...
주제는 my.cnf파일을 수정한 후에 create database를 euckr로 생성해야함.
====================================================
/etc/mysql/my.cnf 파일에서..
[client]
...
default-character-set = euckr
[mysqld]
...
default-character-set=euckr
init_connect = SET collation_connection = euckr_korean_ci
init_connect = SET NAMES euckr
charater-set-server = euckr
collation-server = euckr_korean_ci
[mysqldump]
...
default-character-set=euckr
[mysql]
default-character-set=euckr
수정후에 mysql을 다시 띄움
==============================================
mysql이 4.1로 업그레이드 되면서 서브쿼리가 지원되게 되어
아마도 많은 사람들이 개발시점에서 한 번쯤은 mysql4.1을 사용할지
고민했으리라 생각합니다.
그러나 아직 제대로된 버전이 아닌관계로 버젓한 메뉴얼이 없어
변화된 localization셋팅때문에 많은 분들이 고생했을 것이라 예상합니다.
mysql4.1에서는 4.0에서처럼 default character set하나만 바꿔주면 끝나질
않습니다. 서버/데이터베이스/테이블/connection/ 심지어 필드
하나하나, 스트링 하나하나까지도 character set과 collation을 설정할 수
있게 되었습니다. 그래서 4.0에서 서비스하던 사이트를 4.1로
데이터를 옮기는 과정에서 한글이 깨지는 현상이 발생합니다.
쉽게 말씀드리면 4단계에 걸쳐서 각각 character set과 collation을
변경해주시면 됩니다. 우선 데이터베이스를 다음과 같이 새로 생성합니다.
>> create database DB_NAME character set euckr collation euckr_korean_ci
그리고 4.0의 데이터를 스크립트로 복사한 다음 각각의 테이블 끝에
붙어있는 character set을 euc-kr 이나 latin1에서 euckr로 변경해줍니다.
(4.1에서 한글의 character set이름이 euc-kr에서 euckr로 변경되었습니다.)
그런 다음 mysql 을 --default-character-set=euckr --default-collation=euckr_korean_ci 의 옵션을 주어 실행시키면서 자료를 덤프받습니다.
>> mysql -uroot -p --default-character-set=euckr --default-collation=euckr_korean_ci < DB_SCRIPT.SQL
(DB_SCRIPT.SQL파일은 4.0에서 받은 데이터 스크립트파일이겠죠.)
그렇게 하면 일단 데이터베이스 어필리케이션(예를 들면 SQLyog같은 프로그램)에서는 정상적으로 데이터를 볼 수 있을 것입니다.
하지만 JDBC를 사용해서 접속하는 경우 connection characterset을 따로
설정해주지 않으면 한글이 깨질 것입니다.
저같은 경우 어플리케이션에서 connection을 얻어오는 즉시
해당 connection을 이용하여 "SET CHARACTER SET euckr"이란
SQL명령을 executeUpdate 시켰서 해결했습니다만 아마도 더 깔끔한
방법이 있을 줄 압니다.
그렇게 하면 mysql4.1.1알파에서도 한글을 문제없이 사용할 수 있습니다.
참고로 그냥 latin1으로 설정한 상태에서도 한글이 사용이 가능하긴 합니다만 order by나 일부 한글로의 검색시에 제대로 검색이 안되는 경우가 발생합니다. 그런 경우 해당 필드만 character set을 설정해서 사용할 수도 있습니다. 예를 들면 latin1으로 저장된 한글을 euckr의 코드셋 순서로 정렬하고 싶을 때 다음과 같이 하면 됩니다.
>> SELECT * FROM table_name ORDER BY k COLLATE euckr_korean_ci
그러면 한글 순서로 정렬이 됩니다.
이 말은 만약 이제까지 latin1으로 잘 써오신 분이라면 정렬을 위해서만 추가적으로 코드를 추가해줄 경우 문제없이 잘 정렬이 됨을 의미하는 것이니 데이터베이스를 통째로 수정할 필요가 없겠지요.
저도 초보라 고생끝에 알아낸 팁입니다. 유용하게 참고하셨으면 좋겠습니다.