Hbase C# Thrift 连接 , 提示 因为队列满或者系统缺乏足够的缓冲空间
2011-12-07 14:31
344 查看
原有方法:
public class HbaseClient : IDisposable
{
public Apache.Hadoop.Hbase.Hbase.Client Client { get; private set; }
protected TBufferedTransport Transport { get; private set; }
private TSocket socket;
/// <summary>
///
/// </summary>
/// <param name="host"></param>
/// <param name="prot"></param>
public HbaseClient(string host, int prot)
{
socket = new TSocket(host, prot);
this.Transport = new TBufferedTransport(socket);
this.Transport.Open();
var protocol = new TBinaryProtocol(Transport);
Client = new Apache.Hadoop.Hbase.Hbase.Client(protocol);
}
/// <summary>
///
/// </summary>
public HbaseClient()
: this(System.Configuration.ConfigurationManager.AppSettings["hbasehost"],
int.Parse(System.Configuration.ConfigurationManager.AppSettings["hbaseport"])
)
{
}
/// <summary>
///
/// </summary>
public void Dispose()
{
this.socket.Close();
this.Transport.Close();
}
}
public static void AddLog(string userid, string ip, DateTime logintime, bool result)
{
using (var hclient = new HbaseClient())
{
string strtime = H.Comm.TimeUtility.DescTimeStamp(logintime).ToString();
string row = H.Comm.StringUtility.FixedLenString(userid, 20) + strtime;
hclient.Client.mutateRow(tableName.ToBytes(), row.ToBytes(),
new List<Apache.Hadoop.Hbase.Mutation> {
new Apache.Hadoop.Hbase.Mutation{ Column= "u:uid".ToBytes(), Value = userid.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:ip".ToBytes(), Value = ip.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:lt".ToBytes(), Value = logintime.ToString().ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:r".ToBytes(), Value = Convert.ToInt16(result).ToString().ToBytes() }
});
}
}
//不断的进行插入操作,看插入到什么情况下会出现问题
static void InsertRunOn()
{
int uid = 1000000;
for (var i = 0; true; i++)
{
string struid = (uid + i).ToString();
string ip = "192.168.1." + (int)(i % 255);
System.DateTime dt = System.DateTime.Now;
if (i % 100 == 0)
Console.WriteLine(i);
H.BLL.LoginLog.AddLog(struid, ip, dt, true);
}
}
运行一会以后就出现错误了。提示 因为队列满或者系统缺乏足够的缓冲空间 之类,
netstat –an 发现本地端口已经用到 65535 , 一直在 timewait 了。
修改(添加)注册表,并重新启动系统:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 下面:
TcpNumConnections
Key: Tcpip\Parameters
取值类型:REG_DWORD - Number
取值范围:0 - 0xfffffe
缺省值:0xfffffe
描述:本参数限制可以同时打开的TCP连接的数量
MaxUserPort
key: Tcpip\Parameters
取值类型:REG_DWORD - Number
取值范围:5000-65534 (十进制)
缺省值:0x1388 (5000 十进制)
描述:控制一个应用程序可以打开的最多端口数量。通常,短命的端口在1024-5000之间分配。
当试图发起5000以上端口的连接,系统将出现WSAENOBUFS(10055)错误:因为队列满或者系统
缺乏足够的缓冲空间。
如何修改TIME_WAIT超时时间以增加连接数。本设置定义了关闭连接前保持TIME_WAIT状态的时长。默认值为240,在一个繁忙的服务器上会将最大连接数限制在大约200/秒。减少该值可以增加最大连接数的限制。
具体操作步骤如下:
1.打开注册表编辑器,找到如下表所示的项。
2.按照下表设置,新建或者修改已有的一个名称为“TcpTimedWaitDelay”的DWORD值。
3.退出注册表编辑器,重新启动或者注销Windows以使改动生效。
设置:
项(系统): [HKEY_LOCAL_MACHINE/System/CurrectControlSet/Services/Tcpip/Parameters]
名称: TcpTimedWaitDelay
类型: REG_DWORD (DWORD 值)
值: 30-300 秒 (十进制)
上面的方法收效甚微,改变方法,做一个 连接池,这样会更有效些。
下面是改进后的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift.Transport;
using Thrift.Protocol;
using System.Threading;
namespace H.HbaseProvider
{
public class HClient : IDisposable
{
private static string host = System.Configuration.ConfigurationManager.AppSettings["hbasehost"];
private static int port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["hbaseport"]);
public bool IsFree;
public Apache.Hadoop.Hbase.Hbase.Client Client;
private TSocket socket;
private TProtocol protocol;
private TTransport Transport;
public HClient()
{
socket = new TSocket(host, port);
this.Transport = new TBufferedTransport(socket);
//Transport.Open();
this.protocol = new TBinaryProtocol(Transport);
this.Client = new Apache.Hadoop.Hbase.Hbase.Client(protocol);
this.IsFree = true;
}
public bool IsOpen
{
get
{
return this.Transport.IsOpen;
}
}
public void Open()
{
this.Transport.Open();
}
public void Close()
{
this.Transport.Close();
}
public void Dispose()
{
IsFree = true;
}
}
/// <summary>
/// Hbase 连接池
/// added by zbw911
/// </summary>
public class HBaseClientPool
{
private static int DEFAULT_COUNT = 10;
private static int MAX_CLIENTCOUNT = 20;
private static List<HClient> clientlist = null;
private static Mutex m_mutex = new Mutex();
static HBaseClientPool()
{
clientlist = new List<HClient>(DEFAULT_COUNT);
for (var i = 0; i < DEFAULT_COUNT; i++)
clientlist.Add(new HClient());
}
public static HClient GetHclient()
{
m_mutex.WaitOne(); //先阻塞
for (var i = 0; i < clientlist.Count; i++)
{
if (clientlist[i].IsFree)
{
if (!clientlist[i].IsOpen)
{
clientlist[i].Open();
}
clientlist[i].IsFree = false;
m_mutex.ReleaseMutex();//释放资源
return clientlist[i];
}
}
if (clientlist.Count > MAX_CLIENTCOUNT) throw new Exception("超出最大HClinet最大个数");
var item = new HClient();
item.Open();
item.IsFree = false;
m_mutex.ReleaseMutex();//释放资源
return item;
}
}
}
使用方法
public static void PoolAddLog(string userid, string ip, DateTime logintime, bool result)
{
using (var hclient = HBaseClientPool.GetHclient())
{
string strtime = H.Comm.TimeUtility.DescTimeStamp(logintime).ToString();
string row = H.Comm.StringUtility.FixedLenString(userid, 20) + strtime;
hclient.Client.mutateRow(tableName.ToBytes(), row.ToBytes(),
new List<Apache.Hadoop.Hbase.Mutation> {
new Apache.Hadoop.Hbase.Mutation{ Column= "u:uid".ToBytes(), Value = userid.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:ip".ToBytes(), Value = ip.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:lt".ToBytes(), Value = logintime.ToString().ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:r".ToBytes(), Value = Convert.ToInt16(result).ToString().ToBytes() }
});
}
}
// 从这里进行变态的插入操作吧
static void PoolInsertRunOn()
{
int uid = 1000000;
for (var i = 0; true; i++)
{
string struid = (uid + i).ToString();
string ip = "192.168.1." + (int)(i % 255);
System.DateTime dt = System.DateTime.Now;
if (i % 100 == 0)
Console.WriteLine(i);
H.BLL.LoginLog.PoolAddLog(struid, ip, dt, true);
}
}
使用上面的方法以后,好多了。
MAX_CLIENTCOUNT 再根据实际环境进行调整吧。
public class HbaseClient : IDisposable
{
public Apache.Hadoop.Hbase.Hbase.Client Client { get; private set; }
protected TBufferedTransport Transport { get; private set; }
private TSocket socket;
/// <summary>
///
/// </summary>
/// <param name="host"></param>
/// <param name="prot"></param>
public HbaseClient(string host, int prot)
{
socket = new TSocket(host, prot);
this.Transport = new TBufferedTransport(socket);
this.Transport.Open();
var protocol = new TBinaryProtocol(Transport);
Client = new Apache.Hadoop.Hbase.Hbase.Client(protocol);
}
/// <summary>
///
/// </summary>
public HbaseClient()
: this(System.Configuration.ConfigurationManager.AppSettings["hbasehost"],
int.Parse(System.Configuration.ConfigurationManager.AppSettings["hbaseport"])
)
{
}
/// <summary>
///
/// </summary>
public void Dispose()
{
this.socket.Close();
this.Transport.Close();
}
}
public static void AddLog(string userid, string ip, DateTime logintime, bool result)
{
using (var hclient = new HbaseClient())
{
string strtime = H.Comm.TimeUtility.DescTimeStamp(logintime).ToString();
string row = H.Comm.StringUtility.FixedLenString(userid, 20) + strtime;
hclient.Client.mutateRow(tableName.ToBytes(), row.ToBytes(),
new List<Apache.Hadoop.Hbase.Mutation> {
new Apache.Hadoop.Hbase.Mutation{ Column= "u:uid".ToBytes(), Value = userid.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:ip".ToBytes(), Value = ip.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:lt".ToBytes(), Value = logintime.ToString().ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:r".ToBytes(), Value = Convert.ToInt16(result).ToString().ToBytes() }
});
}
}
//不断的进行插入操作,看插入到什么情况下会出现问题
static void InsertRunOn()
{
int uid = 1000000;
for (var i = 0; true; i++)
{
string struid = (uid + i).ToString();
string ip = "192.168.1." + (int)(i % 255);
System.DateTime dt = System.DateTime.Now;
if (i % 100 == 0)
Console.WriteLine(i);
H.BLL.LoginLog.AddLog(struid, ip, dt, true);
}
}
运行一会以后就出现错误了。提示 因为队列满或者系统缺乏足够的缓冲空间 之类,
netstat –an 发现本地端口已经用到 65535 , 一直在 timewait 了。
修改(添加)注册表,并重新启动系统:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 下面:
TcpNumConnections
Key: Tcpip\Parameters
取值类型:REG_DWORD - Number
取值范围:0 - 0xfffffe
缺省值:0xfffffe
描述:本参数限制可以同时打开的TCP连接的数量
MaxUserPort
key: Tcpip\Parameters
取值类型:REG_DWORD - Number
取值范围:5000-65534 (十进制)
缺省值:0x1388 (5000 十进制)
描述:控制一个应用程序可以打开的最多端口数量。通常,短命的端口在1024-5000之间分配。
当试图发起5000以上端口的连接,系统将出现WSAENOBUFS(10055)错误:因为队列满或者系统
缺乏足够的缓冲空间。
如何修改TIME_WAIT超时时间以增加连接数。本设置定义了关闭连接前保持TIME_WAIT状态的时长。默认值为240,在一个繁忙的服务器上会将最大连接数限制在大约200/秒。减少该值可以增加最大连接数的限制。
具体操作步骤如下:
1.打开注册表编辑器,找到如下表所示的项。
2.按照下表设置,新建或者修改已有的一个名称为“TcpTimedWaitDelay”的DWORD值。
3.退出注册表编辑器,重新启动或者注销Windows以使改动生效。
设置:
项(系统): [HKEY_LOCAL_MACHINE/System/CurrectControlSet/Services/Tcpip/Parameters]
名称: TcpTimedWaitDelay
类型: REG_DWORD (DWORD 值)
值: 30-300 秒 (十进制)
上面的方法收效甚微,改变方法,做一个 连接池,这样会更有效些。
下面是改进后的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift.Transport;
using Thrift.Protocol;
using System.Threading;
namespace H.HbaseProvider
{
public class HClient : IDisposable
{
private static string host = System.Configuration.ConfigurationManager.AppSettings["hbasehost"];
private static int port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["hbaseport"]);
public bool IsFree;
public Apache.Hadoop.Hbase.Hbase.Client Client;
private TSocket socket;
private TProtocol protocol;
private TTransport Transport;
public HClient()
{
socket = new TSocket(host, port);
this.Transport = new TBufferedTransport(socket);
//Transport.Open();
this.protocol = new TBinaryProtocol(Transport);
this.Client = new Apache.Hadoop.Hbase.Hbase.Client(protocol);
this.IsFree = true;
}
public bool IsOpen
{
get
{
return this.Transport.IsOpen;
}
}
public void Open()
{
this.Transport.Open();
}
public void Close()
{
this.Transport.Close();
}
public void Dispose()
{
IsFree = true;
}
}
/// <summary>
/// Hbase 连接池
/// added by zbw911
/// </summary>
public class HBaseClientPool
{
private static int DEFAULT_COUNT = 10;
private static int MAX_CLIENTCOUNT = 20;
private static List<HClient> clientlist = null;
private static Mutex m_mutex = new Mutex();
static HBaseClientPool()
{
clientlist = new List<HClient>(DEFAULT_COUNT);
for (var i = 0; i < DEFAULT_COUNT; i++)
clientlist.Add(new HClient());
}
public static HClient GetHclient()
{
m_mutex.WaitOne(); //先阻塞
for (var i = 0; i < clientlist.Count; i++)
{
if (clientlist[i].IsFree)
{
if (!clientlist[i].IsOpen)
{
clientlist[i].Open();
}
clientlist[i].IsFree = false;
m_mutex.ReleaseMutex();//释放资源
return clientlist[i];
}
}
if (clientlist.Count > MAX_CLIENTCOUNT) throw new Exception("超出最大HClinet最大个数");
var item = new HClient();
item.Open();
item.IsFree = false;
m_mutex.ReleaseMutex();//释放资源
return item;
}
}
}
使用方法
public static void PoolAddLog(string userid, string ip, DateTime logintime, bool result)
{
using (var hclient = HBaseClientPool.GetHclient())
{
string strtime = H.Comm.TimeUtility.DescTimeStamp(logintime).ToString();
string row = H.Comm.StringUtility.FixedLenString(userid, 20) + strtime;
hclient.Client.mutateRow(tableName.ToBytes(), row.ToBytes(),
new List<Apache.Hadoop.Hbase.Mutation> {
new Apache.Hadoop.Hbase.Mutation{ Column= "u:uid".ToBytes(), Value = userid.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:ip".ToBytes(), Value = ip.ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:lt".ToBytes(), Value = logintime.ToString().ToBytes() },
new Apache.Hadoop.Hbase.Mutation{ Column= "u:r".ToBytes(), Value = Convert.ToInt16(result).ToString().ToBytes() }
});
}
}
// 从这里进行变态的插入操作吧
static void PoolInsertRunOn()
{
int uid = 1000000;
for (var i = 0; true; i++)
{
string struid = (uid + i).ToString();
string ip = "192.168.1." + (int)(i % 255);
System.DateTime dt = System.DateTime.Now;
if (i % 100 == 0)
Console.WriteLine(i);
H.BLL.LoginLog.PoolAddLog(struid, ip, dt, true);
}
}
使用上面的方法以后,好多了。
MAX_CLIENTCOUNT 再根据实际环境进行调整吧。
相关文章推荐
- 解决大量TCPIP连接后出现“因为系统缺乏足够缓冲区空间或者因为队列已满无法执行套接字上操作”的问题
- 解决大量TCPIP连接后出现“因为系统缺乏足够缓冲区空间或者因为队列已满无法执行套接字上操作”的问题
- no buffer space available、由于系统缓冲空间不足或队列已满,不能执行套接字上的操作
- word2003保存文时总是提示“文档被保存,但是语音识别的数据丢失,因为没有足够的空间存储这些数据。确保没有录音时关闭麦克风,并检查磁盘上的存储空间。[转]
- VS2010 或Blend 在XP系统提示 没有足够的空间完成操作 解决方法
- utorrent红种:由于系统缓冲区空间不足或者队列已满...
- C#通过thrift连接hbase操作步骤
- C#通过Thrift连接查询HBase主要方法总结
- 【转】硬盘里有足够的空间却提示没有足够的磁盘空间--解决办法
- [原创]Python通过Thrift连接HBase
- 织梦CMS 文章详情报错—你会看到这个提示,那是因为你的系统无法识别某栏目的模型信息,或者你新建模型后.....
- C#连接solr时提示 java内存异常 (jetty和tomcat哪个更High) java.lang.OutOfMemoryError
- php/perl/python , 通过thrift 连接 hbase,进行条件过滤选择
- hdu1257最少拦截系统(动态规划之最长递增子序列或者用类队列来算)
- 大于4G的文件拷贝到空间足够的U盘中,总是提示空间不足,该怎么办
- 极光推送C#版本在XP系统下提示“基础连接已经关闭: 接收时发生意外错误”的解决方案
- 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作
- Linux或者Mac系统使用SSH连接树莓派
- SQLServer不存在或访问被拒绝或者提示连接超时
- Win7 64系统连接局域网打印机提示无法连接