一、sphinx中searchd搜索服务命令的一些有用的选项-io、cpu统计日志及status状态信息
sphinx有两大关键工具,一个是indexer索引,另一个就是搜索服务searchd。通常searchd就是作为一个服务指定配置文件启动,但实际searchd还有其它一些有意思的选项,比如:
--stop选项停止searchd服务,send SIGTERM to currently running searchd
--stopwait 也是停止服务,在停止时能更好的保存信息,文档:send SIGTERM and wait until actual exit
--status 选项查看sphinx的运行状态:包括运行时间,连接数等详细数据。
--console 用来强制searchd以控制台模式启动,方便调试
--iostats 当使用日志时(sphinx.conf启用query_log选项)启用--iostats会对每条查询输出关于查询过程中发生的输入输出操作的详细信息。
--cpustats 使实际CPU时间报告(不光是实际度量时间(wall time))出现在查询日志文件(每条查询输出一次)和状态报告(累加之后)中。
--console 用来强制searchd以控制台模式启动
在停止sphinx服务的时候,通过可能是直接强硬地KILL掉进程,虽然一般也不出意外,但最好是能使用searchd自带的停止命令,--stop和--stopwait选项。推荐使用--stopwait时,不过我在使用--stopwait时发现执行后searchd并不是立即就停止服务,查看仍然有searchd进程,但是已经不再监控原来的端口。而此时searchd也不能启动新的进程,grep searchd还会发现有一些addr2line命令在执行,像是出了什么错误。不确定是--stopwait导致的还是什么问题。启动后使用--status查看sphinx的状态信息。
#使用--stop选项停止searchd服务
[dev@SERVER coreseek]$ sudo bin/searchd -c etc/market.conf
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/market.conf'...
listening on all interfaces, port=9314
precaching index 'market'
rotating index 'market': success
precached 1 indexes in 0.295 sec
[dev@SERVER coreseek]$ ps -ef | grep searchd
root 25109 1 0 15:50 ? 00:00:00 bin/searchd -c etc/market.conf
root 25110 25109 7 15:50 ? 00:00:00 bin/searchd -c etc/market.conf
30548 25115 21570 0 15:50 pts/1 00:00:00 grep searchd
#使用--status查看统计信息
[dev@SERVER sphinx]$ sudo bin/searchd --config etc/market.conf --status
Sphinx 2.1.7-release (rel21-r4638)
Copyright (c) 2001-2014, Andrew Aksyonoff
Copyright (c) 2008-2014, Sphinx Technologies Inc (http://sphinxsearch.com)
using config file 'etc/market.conf'...
searchd status
--------------
uptime: 254
connections: 6
maxed_out: 0
command_search: 0
command_excerpt: 0
command_update: 0
command_keywords: 0
command_persist: 0
command_status: 1
command_flushattrs: 0
agent_connect: 0
agent_retry: 0
queries: 0
dist_queries: 0
query_wall: 0.000
query_cpu: OFF
dist_wall: 0.000
dist_local: 0.000
dist_wait: 0.000
query_reads: OFF
query_readkb: OFF
query_readtime: OFF
avg_query_wall: 0.000
avg_query_cpu: OFF
avg_dist_wall: 0.000
avg_dist_local: 0.000
avg_dist_wait: 0.000
avg_query_reads: OFF
avg_query_readkb: OFF
avg_query_readtime: OFF
[dev@SERVER coreseek]$ sudo bin/searchd -c etc/market.conf --stop
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/market.conf'...
stop: successfully sent SIGTERM to pid 25110
[dev@SERVER coreseek]$ ps -ef | grep search
30548 25121 21570 0 15:51 pts/1 00:00:00 grep search
[dev@SERVER coreseek]$
#再次启动后执行--stopwait选项,两个命令在输出是一样的。
[dev@SERVER coreseek]$ sudo bin/searchd -c etc/market.conf --stopwait
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/market.conf'...
stop: successfully sent SIGTERM to pid 25125
#addr2line 不知道是什么情况
[dev@SERVER coreseek]$ps -ef | grep searchd
root 25140 1 0 15:52 ? 00:00:00 bin/searchd --config etc/market.conf
root 25828 25140 0 15:55 ? 00:00:00 bin/searchd --config etc/market.conf
root 25829 25828 17 15:55 ? 00:00:00 addr2line -e bin/searchd 0x6545b0 0x490f63 0x6e60eca0 0x6de7b89e 0x517e56 0x52ed97 0x52f32e 0x53a40a 0x5801bf 0x55e636 0x48f5c7 0x4ca5e4 0x4f4587 0x4f6325 0x6de1d9c4 0x48dc69
30548 25831 21570 0 15:55 pts/1 00:00:00 grep searchd
#searchd进程服务仍然在执行,但是已经不再监控原来的端口:
[dev@SERVER coreseek]$ sudo bin/searchd --config etc/market.conf --status
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/market.conf'...
WARNING: failed to connect to 0.0.0.0:9314: Connection refused
searchd搜索服务启动时还可以带上--iostats --cpustats选项,分别指示打开io和cpu统计并记录日志。但只会记录通过searchd监听的端口发来的请求才会进行记录,而通过如下使用search命令进行直接查询的方式则不会进行记录:
[dev@SERVER coreseek]$ bin/search -c etc/market.conf 中国人力资源网
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
Copyright (c) 2007-2011,
Beijing Choice Software Technologies Inc (http://www.coreseek.com)
using config file 'etc/market.conf'...
index 'market': query '中国人力资源网 ': returned 4 matches of 4 total in 0.004 sec
displaying matches:
1. document=64443, weight=7574, downloads=2, installs=131, boutique=0, boutique_pc=0, title=中国人力资源网, py=_ z h o n g g u o r e n l i z i y u a n w a n g, ipy=_ z g r l z y w, style=2
2. document=156022, weight=7574, downloads=0, installs=15247, boutique=0, boutique_pc=0, title=中国人力资源网, py=_ z h o n g g u o r e n l i z i y u a n w a n g, ipy=_ z g r l z y w, style=14
3. document=178156, weight=7574, downloads=2, installs=12, boutique=0, boutique_pc=0, title=中国人力资源网, py=_ z h o n g g u o r e n l i z i y u a n w a n g, ipy=_ z g r l z y w, style=7
4. document=303947, weight=7574, downloads=0, installs=0, boutique=0, boutique_pc=0, title=中国人力资源网, py=_ z h o n g g u o r e n l i z i y u a n w a n g, ipy=_ z g r l z y w, style=25
words:
1. '中': 20817 documents, 20996 hits
2. '国': 23230 documents, 23532 hits
3. '人': 26755 documents, 27327 hits
4. '力': 6998 documents, 7031 hits
5. '资': 2688 documents, 2708 hits
6. '源': 1625 documents, 1626 hits
7. '网': 19727 documents, 19821 hits
#以上的请求并不会记录到日志中,而通过端口发过来的请求,可以看一下开启--iostats --cpustats选项和不开启的记录差别。
#开启--iostats --cpustats ==> query.log <==
[Fri Mar 15 16:35:56.788 2019] 0.007 sec [all/0/rel 11 (0,20)] [market] [ios=5 kb=342.1 ioms=0.4 cpums=4.8] 中国人力
[Fri Mar 15 16:39:46.330 2019] 0.004 sec [all/0/rel 1 (0,20)] [market] [ios=8 kb=378.3 ioms=0.3 cpums=4.4] 中国人力资源平台
#不开启--iostats --cpustats ==> query.log <==
[Fri Mar 15 16:40:21.512 2019] 0.005 sec [all/0/rel 1 (0,20)] [market] 中国人力资源平台
[Fri Mar 15 16:42:25.464 2019] 0.004 sec [all/0/rel 1 (0,20)] [market] 中国人力资源平台
#另外开启--console选项会直接将query的日志显示在控制台
[dev@SERVER coreseek]$ sudo bin/searchd --config etc/market.conf --console
Coreseek Fulltext 4.1 [ Sphinx 2.0.2-dev (r2922)]
......
accepting connections
[Fri Mar 15 16:42:32.493 2019] 0.004 sec [all/0/rel 1 (0,20)] [market] 中国人力资源平台
searchd其它一些选项:
-p, --port <port> listen on given port (overrides config setting)
-l, --listen <spec> listen on given address, port or path (overrides config settings)
指定searchd监听的端口,用于调试。
-i, --index <index> only serve one given index
强制searchd只提供针对指定索引的搜索服务。用于调试。
--logdebug enable additional debug information logging
显示一些附加的调试信息,我到是试过加了,不过没发现其它调试信息
--nodetach do not detach into background
二、 转存 nginx中的worker_connections配置和获取处理请求的机制
如下文转自:http://tengine.taobao.org/book/chapter_02.html 如有需要请联系我删除。
在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件。利用nginx封装的connection,我们可以很方便的使用nginx来处理与连接相关的事情,比如,建立连接,发送与接受数据等。而nginx中的http请求的处理就是建立在connection之上的,所以nginx不仅可以作为一个web服务器,也可以作为邮件服务器。当然,利用nginx提供的connection,我们可以与任何后端服务打交道。
结合一个tcp连接的生命周期,我们看看nginx是如何处理一个连接的。首先,nginx在启动时,会解析配置文件,得到需要监听的端口与ip地址,然后在nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的ip地址端口,再listen),然后再fork出多个子进程出来,然后子进程会竞争accept新的连接。此时,客户端就可以向nginx发起连接了。当客户端与服务端通过三次握手建立好一个连接后,nginx的某一个子进程会accept成功,得到这个建立好的连接的socket,然后创建nginx对连接的封装,即ngx_connection_t结构体。接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。最后,nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了。
当然,nginx也是可以作为客户端来请求其它server的数据的(如upstream模块),此时,与其它server创建的连接,也封装在ngx_connection_t中。作为客户端,nginx先获取一个ngx_connection_t结构体,然后创建socket,并设置socket的属性( 比如非阻塞)。然后再通过添加读写事件,调用connect/read/write来调用连接,最后关掉连接,并释放ngx_connection_t。
在nginx中,每个进程会有一个连接数的最大上限,这个上限与系统对fd的限制不一样。在操作系统中,通过ulimit -n,我们可以得到一个进程所能够打开的fd的最大数,即nofile,因为每个socket连接会占用掉一个fd,所以这也会限制我们进程的最大连接数,当然也会直接影响到我们程序所能支持的最大并发数,当fd用完后,再创建socket时,就会失败。nginx通过设置worker_connectons来设置每个进程支持的最大连接数。如果该值大于nofile,那么实际的最大连接数是nofile,nginx会有警告。nginx在实现时,是通过一个连接池来管理的,每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。
在这里,很多人会误解worker_connections这个参数的意思,认为这个值就是nginx所能建立连接的最大值。其实不然,这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。
那么,我们前面有说过一个客户端连接过来后,多个空闲的进程,会竞争这个连接,很容易看到,这种竞争会导致不公平,如果某个进程得到accept的机会比较多,它的空闲连接很快就用完了,如果不提前做一些控制,当accept到一个新的tcp连接后,因为无法得到空闲连接,而且无法将此连接转交给其它进程,最终会导致此tcp连接得不到处理,就中止掉了。很显然,这是不公平的,有的进程有空余连接,却没有处理机会,有的进程因为没有空余连接,却人为地丢弃连接。那么,如何解决这个问题呢?首先,nginx的处理得先打开accept_mutex选项,此时,只有获得了accept_mutex的进程才会去添加accept事件,也就是说,nginx会控制进程是否添加accept事件。nginx使用一个叫ngx_accept_disabled的变量来控制是否去竞争accept_mutex锁。在第一段代码中,计算ngx_accept_disabled的值,这个值是nginx单进程的所有连接总数的八分之一,减去剩下的空闲连接数量,得到的这个ngx_accept_disabled有一个规律,当剩余连接数小于总连接数的八分之一时,其值才大于0,而且剩余的连接数越小,这个值越大。再看第二段代码,当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,并且将ngx_accept_disabled减1,于是,每次执行到此处时,都会去减1,直到小于0。不去获取accept_mutex锁,就是等于让出获取连接的机会,很显然可以看出,当空余连接越少时,ngx_accept_disable越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去accept,自己的连接就控制下来了,其它进程的连接池就会得到利用,这样,nginx就控制了多进程间连接的平衡了。
ngx_accept_disabled = ngx_cycle->connection_n / 8
- ngx_cycle->free_connection_n;
if (ngx_accept_disabled > 0) {
ngx_accept_disabled--;
} else {
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return;
}
if (ngx_accept_mutex_held) {
flags |= NGX_POST_EVENTS;
} else {
if (timer == NGX_TIMER_INFINITE
|| timer > ngx_accept_mutex_delay)
{
timer = ngx_accept_mutex_delay;
}
}
}