[Erlang]通用的erlang优化设置



    设置是我在多个项目中通用的,不过根据应用场景的不同,还会有其它细调,就不在这一一说明了。  - Sunface


 一、 erl启动时参数:

+K true

开启epoll调度,在linux中开启epoll,会大大增加调度的效率

+A 100

        异步线程池,为某些port调用服务

+P 1024000

最大进程数

+Q 65535

最大port数

+sbt db

绑定调度器,绑定后调度器的任务队列不会在各个CPU线程之间跃迁,结合sub使用,可以让CPU负载均衡的同时也避免了大量的跃迁发生。

注意:一个linux系统中,最好只有一个evm开启此选项,若同时有多个erlang虚拟机在系统中运行,还是关闭为好

+sub true

开启CPU负载均衡,false的时候是采用的CPU密集调度策略,优先在某个CPU线程上运行任务,直到该CPU负载较高为止。

+swct eager
此选项设置为eager后,CPU将更频繁的被唤醒,可以增加CPU利用率

+spp true
开启并行port并行调度队列,当开启后会大大增加系统吞吐量,如果关闭,则会牺牲吞吐量换取更低的延迟。

+zdbbl 65536

分布式erlang的端口buffer大小,当buffer满的时候,向分布式的远程端口发送消息会阻塞


二、erlang内部进程启动参数

示例:创建一个新进程并进行注册,该进程是全局唯一的自增ID生成进程,因此无法做多进程处理,这个时候单进程的性能就是至关重要的

首先,出于性能和功能考虑,这个进程不是gen_server;其次进行了部分参数调优能

register(num_generator, spawn_opt(?MODULE, init, [],[{priority,high},{scheduler,0},{min_heap_size, 65536 * 2},{min_bin_vheap_size,65536 * 2}])).

参数讲解:

1.priority 

er lang是公平调度策略,因此默认情况下每个进程得到的运行时间片是相同的:2000reductions,但是对于我们的应用场景来说,这个进程应该是优先级较高的,需要得到更多的调度,因此设置为high,还可以设置为max,但是max是系统进程的预留优先级,用high即可

2. scheduler 

将该进程绑定到指定的scheduler上,防止进程的任务被scheduler分配来分配去,可以减少CPU调用,注意这个和+sbt db是不同的,+sbt db是防治调度器的任务队列在CPU线程间跃迁,scheduler是为了防止进程在时间片切换过程中被分配给其它的调度器

3.min_heap_size

进程初始堆大小,用内存换CPU的典型做法,增大初始大小,可以显著降低GC次数和内存再分配次数

4.min_bin_vheap_size

进程初始二进制堆大小,当该进程对于binary数据的处理交换很多时,可以获得和增大min_heap_size一样的效果



 三、port(socket)调优

示例:服务器监听端口,接受客户端请求。典型应用场景web服务器,需要实现高吞吐,低延迟的目标

  

Res = gen_tcp:listen(Port, [binary,

{reuseaddr, true},

{nodelay, true},

{delay_send,true},

  {high_watermark,64 * 1024},

{send_timeout, 30000},

{send_timeout_close, true},

{keepalive, true}])


参数详解:

binary:

接收到客户端的消息后,作为binary来处理,binary在erlang中是很高效的数据结构,超过64字节,就是全局保存的,因此在很多操作下是不需要复制的,仅仅复制binary的指针即可,详细请搜索refc binary,注意:binary大量使用需要有丰富的经验,不然可能会内存泄漏

reuseaddr:

允许系统复用port,对于高吞吐的系统,这个参数很重要,请搜索:linux port 复用

nodelay:

开启linux中的TCP_NODELAY参数,请搜索:TCP_NODELAY 40毫秒延迟

delay_send:

默认的erlang port消息发送,是直接发送,若失败则排队处理,然后由调度器进行队列poll操作,如果设置为true,那么就不尝试直接发送,而且扔进队列,等待poll,开启选项会增加一点点消息延迟,换来吞吐量的大量提升

high_watermark:

port的发送缓存,缓存满了后,下次发送会直接阻塞,直到缓存低于某个阈值low_watermark。如果是密集网络IO系统,请增大该buffer,避免发送阻塞

send_timeout:

在high_watermark中提到了发送阻塞,如果阻塞超过这个时间,那么就会超时,发送直接返回,停止发送

send_timeout_close:

如果发生了send_timeout同时设置了send_timeout_close选项,那么超时后,会直接关闭socket.如果发送进程不是很重要,例如web用户进程,强烈建议开启这个选项,当发送30秒超时的时候,就说明该用户出现了很大的麻烦,断开连接是最理想的做法,否则可能出现很多奇怪的bug.

keepalive:

遵循HTTP/1.1协议的keepalive规定,这个根据业务需求选择是否开启,如果同一个客户端会连续发起http请求,那么建议设置为true,避免多次TCP握手


示例:服务器发起大量的http请求,在优化了参数后,同样的吞吐量所耗费的时间是未优化前的1/3 - 1/2(经过严苛的测试得出的数据)

 

inets:start(),

  httpc:set_options([{max_keep_alive_length,500},{max_sessions,100},{nodelay,true},{reuseaddr,true}]),

参数详解:

max_keep_alive_length:  

在同一条http连接上允许发送的最大包数,默认为5,超过5个包,就会重连

max_sessions:

跟目标服务器之间最大的并行http连接数目,大大的增加了数据上行吞吐量

nodelay_true:

见上文

reuseaddr:

见上文



先写这么多,以后会陆续更新,如果这篇文章对你有帮助,请留言支持,一个字一个字的敲也是很辛苦的 ;)

你可能感兴趣的:([Erlang]通用的erlang优化设置)