GlusterFS是一个开源的分布式文件系统,实际使用中有以下问题:
GlusterFS为了保证客户端连接的时候是root帐户,限制只接受来自客户端1024以下的端口。这样产生两个问题:一是1024以下有许多重要的系统端口可能被GlusterFS占用;二是在连接多个卷、server机器过多(数百台)的时候,会发生端口不够用。
解决办法:将客户端端口限制在800到1024,并复用端口,修改代码如下:
--- glusterfs-2.0.7/transport/socket/src/name.c 2009-10-01 21:19:54.000000000 +0800
+++ glusterfs-2.0.7-1117/transport/socket/src/name.c 2009-10-14 19:27:54.000000000 +0800
@@ -22,6 +22,7 @@
#include <errno.h>
#include <netdb.h>
#include <string.h>
+#include <time.h>
#ifdef CLIENT_PORT_CEILING
#undef CLIENT_PORT_CEILING
@@ -49,19 +50,24 @@ af_inet_bind_to_port_lt_ceiling (int fd,
{
int32_t ret = -1;
/* struct sockaddr_in sin = {0, }; */
+ static const uint16_t base = 800;
+ ceiling -= base;
uint16_t port = ceiling - 1;
+ uint16_t off = (time(NULL) + rand()) % ceiling; //使初始端口随机
while (port)
{
+ uint16_t rport = (port+off)%ceiling + base;
+
switch (sockaddr->sa_family)
{
case AF_INET6:
- ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port);
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (rport);
break;
case AF_INET_SDP:
case AF_INET:
- ((struct sockaddr_in *)sockaddr)->sin_port = htons (port);
+ ((struct sockaddr_in *)sockaddr)->sin_port = htons (rport);
break;
}
@@ -403,6 +409,7 @@ client_bind (transport_t *this,
int sock)
{
int ret = 0;
+ int opt = 1;
*sockaddr_len = sizeof (struct sockaddr_in6);
switch (sockaddr->sa_family)
@@ -412,6 +419,8 @@ client_bind (transport_t *this,
*sockaddr_len = sizeof (struct sockaddr_in);
case AF_INET6:
+ ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ &opt, sizeof (opt)); //复用端口,参考http://blog.youkuaiyun.com/liusujian02/archive/2007/12/18/1944520.aspx
ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
*sockaddr_len, CLIENT_PORT_CEILING);
if (ret == -1) {
GlusterFS为了保证客户端连接的时候是root帐户,限制只接受来自客户端1024以下的端口。这样产生两个问题:一是1024以下有许多重要的系统端口可能被GlusterFS占用;二是在连接多个卷、server机器过多(数百台)的时候,会发生端口不够用。
解决办法:将客户端端口限制在800到1024,并复用端口,修改代码如下:
--- glusterfs-2.0.7/transport/socket/src/name.c 2009-10-01 21:19:54.000000000 +0800
+++ glusterfs-2.0.7-1117/transport/socket/src/name.c 2009-10-14 19:27:54.000000000 +0800
@@ -22,6 +22,7 @@
#include <errno.h>
#include <netdb.h>
#include <string.h>
+#include <time.h>
#ifdef CLIENT_PORT_CEILING
#undef CLIENT_PORT_CEILING
@@ -49,19 +50,24 @@ af_inet_bind_to_port_lt_ceiling (int fd,
{
int32_t ret = -1;
/* struct sockaddr_in sin = {0, }; */
+ static const uint16_t base = 800;
+ ceiling -= base;
uint16_t port = ceiling - 1;
+ uint16_t off = (time(NULL) + rand()) % ceiling; //使初始端口随机
while (port)
{
+ uint16_t rport = (port+off)%ceiling + base;
+
switch (sockaddr->sa_family)
{
case AF_INET6:
- ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (port);
+ ((struct sockaddr_in6 *)sockaddr)->sin6_port = htons (rport);
break;
case AF_INET_SDP:
case AF_INET:
- ((struct sockaddr_in *)sockaddr)->sin_port = htons (port);
+ ((struct sockaddr_in *)sockaddr)->sin_port = htons (rport);
break;
}
@@ -403,6 +409,7 @@ client_bind (transport_t *this,
int sock)
{
int ret = 0;
+ int opt = 1;
*sockaddr_len = sizeof (struct sockaddr_in6);
switch (sockaddr->sa_family)
@@ -412,6 +419,8 @@ client_bind (transport_t *this,
*sockaddr_len = sizeof (struct sockaddr_in);
case AF_INET6:
+ ret = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
+ &opt, sizeof (opt)); //复用端口,参考http://blog.youkuaiyun.com/liusujian02/archive/2007/12/18/1944520.aspx
ret = af_inet_bind_to_port_lt_ceiling (sock, sockaddr,
*sockaddr_len, CLIENT_PORT_CEILING);
if (ret == -1) {
本文介绍了解决GlusterFS在大规模部署时遇到的端口不足问题的方法。通过调整客户端端口范围并启用端口复用来提高系统的可用性和扩展性。
3120

被折叠的 条评论
为什么被折叠?



