mysql的profiling

下面是我的一些操作简单的过一遍好了。
1)先打开profiling ==> set profiling = 1;
mysql> set profiling = 1;
Query OK, 0 rows affected (0.00 sec)
2) 执行查query操作mysql> select * from player where id = 12;
3)show profiles; 显示所有的profile 选择想查看的Query_ID
mysql> show profiles;
+———-+————+—————————————+
| Query_ID | Duration | Query [...]

Tags: ,

Leave a Comment

mysql 加载tcmalloc耗光内存

最新一些项目发现内存总是不够用,真的让人郁闷的事情,下面的参数
Mem: 12301452k total, 11532928k used, 768524k free, 74712k buffers
Swap: 2031608k total, 208k used, 2031400k free, 3048936k cached
天啊,12G的内存就这样被吃掉了,真是有点恐怖啊。
这时候我就开始gg,百度找资料了,,突然想到装过一个tcmalloc 来再加载 mysql
tcmalloc在为线程分配内存的时候,会比glibc之类的malloc分配的稍微多些,它倾向于稳定,避免大起大落。
经过搜索一番,发现也有人遇到和我一样的问题都是因为装了tcmalloc而内存耗尽。
于是
show variables like ‘%thread%’;
show status like ‘%thread%’;
查看一番,发现Threads_created比较大,,估计mysql线程重用程度比较低了,,于是开始调整了几个参数
innodb_thread_concurrency=20
thread_cache_size = 500
thread_concurrency = 20
然后再观察几个小时,好像内存稳定了,,
真是太好了,,再继续观察几天吧。

Tags:

Leave a Comment

erlang的进程退出

今天工作中同事做组队功能遇到一个问题,
就是当玩家组队的时候会创建一个进程,这个进程是个三级进程,就是它前面还有父进程。
然后我们想现实的是当我们一级进程关闭的时候这个子进程也会一起关闭,最后发现一级进程关闭后,它的子进程也就是2级进程是关闭了,可是3级进程还是存在,这时候挺郁闷的,为什么不会一起关闭呢,,,
经过多番实验,最后发现在2级进程后面加入exit(),便可实现了….
呵呵,其实也就是个小小笔记,充实日记。

Tags:

Leave a Comment

mysql prepared statement

终于下定决心把mnesia换成熟悉的mysql了,,亲密度挺高的,因为mysql用得比较得心应手,感觉挺好。
下了一个erlang mysql 第三方类库并看了下使用例子,如下


mysql:start_link(p1, "localhost", "root", "password", "test"),
mysql:connect(p1, "localhost", undefined, "root", "password", "test",true),
Result1 = mysql:fetch(p1, < <"SELECT * FROM developer">>),
mysql:prepare(update_developer_country, < <"UPDATE developer SET country=? where name like ?">>),
mysql:execute(p1, update_developer_country, [< <"Sweden">>, < <"%Wiger">>]),

使用了一个预处理,开始感觉挺奇怪的,因为以前做PHP的项目基本都没有使用,,几乎也没有听说有谁在mysql上使用。
经过同事查找一些资料和做一些测试,我们很快就有了结果,mysql:prepare并没有直接写入sql快,而且效率挺低的,
具体看看以下分析
1- 执行过程中多了2次交互。
2- Mysql的Prepared Statement目前是有问题的,执行过程中命中率不高,而且可能返回错误。
http://lists.mysql.com/dotnet/1178
3- 服务端的Prepared Statement有两种,一种采用传输二进制的方法,另外一种则采用文本方式传输。Erlang的Mysql驱动程序恰好使用了后者。

Tags: ,

Leave a Comment

mnesia 分布式

Mnesia做分布式比较简单,设置一下参与即可
譬如节点1:
启动参数:erl +P 10240+K true -smp disable -name sd1@127.0.0.1 -setcookie sd2 -config log -s sd server_start
那么节点2:
启动参数:erl -smp disable -name sd2@127.0.0.1 -setcookie sd2 -mnesia extra_db_nodes ["'sd1@127.0.0.1'"] -config log -s sd gateway_start
这时候tv:start().查看数据库内容,,发现数据已经COPY到内存里了。。
mnesia:info().
查看参与如下
—> Processes holding locks < ---
---> Processes waiting for locks < ---
---> Participant transactions < ---
---> Coordinator transactions < ---
---> Uncertain transactions < ---
---> Active [...]

Tags: ,

Leave a Comment

erlang 的进程瓶颈

erlang 的进程瓶颈,这个是我不愿意看到的,不过还是得面对的问题,当我痴迷于erlang能创建千千万万进程的时候,最终发现却它也会有不足,情况是这样,当N多进程访问一个进程,或者当前进程消息量特别大的时候就会出现这个进程消息队列无比增大,速度急速下降,接着就timeout,最后就over了。OH~~~MYLIDY GAGA了。。
网上找了很多解决方式,都没有发现比较直接的,因为erlang调度器进程的消息队列设置就是这样了,我们也只有痛苦的接受了,所谓上有对策下有政策,也只能修改当前的架构了。
1.以数量取胜,把这些进程复制N份设置process_flag(priority, max),平均分担压力,感觉这种方法最简单了。
2.集中力量,发挥erlang优势。把这些进程,独力放到一个节点,(这个架构改动比较大了,不过相对改好后扩展性就更好)
总结,这一切都是从架构出发了。

Tags:

Leave a Comment

Supervisor – 监控树

Supervisor Behaviour是一个用来实现一个supervisor进程来监控其他子进程的模块
子进程可以是另一个supervisor,也可以是一个worker进程
worker进程一般使用gen_event,gen_fsm或gen_server behaviour来实现
一个使用该模块来实现的supervisor有一个接口方法的标准集,包括跟踪和错误报告的功能
supervisor用来构建一个分层进程结构,称为supervision tree,这是组织一个容错系统的好方式
1,Supervision原则
supervisor负责启动、停止和监控它的子进程
supervisor在必要时通过重启它的子进程来保持它们活着
supervisor的子被定义为一个子规范的list
当supervisor启动时,子进程按list从左至右的顺序启动
当supervisor终止时,它首先按启动顺序的反顺序终止它的子进程
2,例子
启动服务器的supervisor的callback模块:

-module(ch_sup).
-behaviour(supervisor).
 
-export([start_link/0]).
-export([init/1]).
 
start_link() ->
supervisor:start_link(ch_sup, []).
 
init(_Args) ->
{ok, {{one_for_one, 1, 60},
[{ch3, {ch3, start_link, []},
permanent, brutal_kill, worker, [ch3]}]}}.

one_for_one是重启策略之一
1和60定义了最大重启频率
tuple {ch3, …}是子规范
3,重启策略
3.1 one_for_one
如果一个子进程停止,则只重启该进程
3.2 one_for_all
如果一个子进程停止,所有其他子进程也停止,然后所有进程重启
3.3 rest_for_one
如果一个子进程停止,则启动顺序中在它之后的所有其他子进程也停止,然后停止的这些进程重启(跟楼上那位不一样)
3.4 simple_one_for_one
一个简化的one_for_one supervisor,所有的子进程都是同样进程类型并且是动态添加的实例
4,最大重启频率
supervisor有一个自带的机制来限制给定时间内重启的次数
这是通过MaxR和MaxT这两个参数来决定的

init(…) ->
{ok, {{RestartStrategy, MaxR, MaxT},
[ChildSpec, …]}}.

如果在最近的MaxT秒之内有超过MaxR次数的重启,则supervisor停止它本身和它所有的子进程
当supervisor停止后,下一个更高级别的supervisor进行下一步动作,重启该停止的supervisor或者终止本身
重启机制的意图是防止一个进程由于某些原因重复性的死掉
5,子规范
这是子规范的类型定义:

Module [...]

Tags: ,

Leave a Comment

gen_fsm 的start_timer和send_event_after使用解析

首先我们看erlang:send_after 和 start_timer
引用:http://www.javaeye.com/topic/634815
这2个API都返回 TimerRef. 用户可以用这个TimerRef来取消定时器. 唯一的差别是在超时的时候发送的消息不同: send_after是Msg, start_timer是{timeout, TimerRef, Msg}.
问题就出在取消timer的时候. 如果这个timer还没有超时的时候, 那么取消就没问题. 如果超时了麻烦就来了, 这个消息已经有可能已经被放到目标进程的消息队列里,等待派遣处理了.
这时候send_after里面存放的是Msg, 那用户如何知道Msg是对于那个TimerRef的呢? 读者可能说, 那我可以在消息里面加入TimerRef. 这个主意不错, 但是问题是在send_after调用返回之前, 你是无法得到TimerRef, 当然也就无从构造这个消息, 那就无法处理这个可能的超时信息, 就会破坏逻辑.
所以erts version 5.4.11 引入了, start_timer来解决这个问题. 它是自动的在超时后, 要发送消息前, 在消息里面添加了{timeout, TimerRef, Msg}, 达到识别的目的.
通过以上文章我们明白了send_after 和 start_timer二者的区别,我们再看看gen_fsm:send_event_after代码其实就是使用了erlang:after_send, gen_fsm:start_timer对应erlang:start_timer,它们返回值都是TimerRef,发出去超时MSG都会调用StateName(Event, StateData)接收事件,也可以用cancel_timer(TimerRef)取消事件,只是send_event_after发出的是MSG,而start_timer发出的是{timeout, TimerRef, Msg}.,所以匹配格式为StateName({timeout, TimerRef, Msg},, StateData)。

Tags: ,

Leave a Comment

erlang 系统信息分析

网上看到的,做个笔记好了。

-module(test).
-export([test/0]).
 
test() ->
SchedId = erlang:system_info(scheduler_id), %调度器id
SchedNum = erlang:system_info(schedulers), %调度器数目
ProcCount = erlang:system_info(process_count), %进程数
ProcLimit = erlang:system_info(process_limit), %进程数量上线
ProcMemUsed = erlang:memory(processes_used), %进程消耗的内存
ProcMemAlloc = erlang:memory(processes), %进程分配的内存
MemTot [...]

Tags:

Leave a Comment

erlang 标志

erlang 初始标志有很多,去了解他们也是有必要的,大家可以根据实际情况去设置好,对性能会有一定的提高。
原文:http://www.erlang.org/doc/man/erl.html
-smp :
enable 启动 然后后面可以跟着 (+S 数量)启动多个调度器
多CPU切换消耗会有点大(适合“小消息,大运算”)
auto 自动根据cpu个数 开启调度器
disable 禁止
+P Number 开启线程数量默认32768.
+K true | [...]

Tags:

Leave a Comment