免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2679 | 回复: 8
打印 上一主题 下一主题

一个服务器设计的问题,应该大家都会遇到,给点建议 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-16 19:39 |只看该作者 |倒序浏览
假设有一台机器A,有1G内存,另外若干台机器(B、C、D……)通过网络TCP向机器A传输数据,A机器把接收到的数据写入硬盘。B、C、D等机器的数据按记录传输,每条记录大小范围:1M~16M。

为了保证每条记录的原子性,B、C、D等机器每次先向A汇报数据量大小,然后再进行数据传输。

汇报数据大小时,A机器会给记录分配一个序号,写入文件时每个记录按序号顺序、原子写入。

B、C、D等机器处理速度和网络速度都不尽相同,因此汇报数据大小之后,记录数据传递到A的顺序可能不一定按分配好的序号顺序到达。

现在要求给A上程序设计一个数据结构,利用该数据结构能高效的接收数据并顺序高效的写入磁盘(也即是不能序号大的记录先写,然后再回写序号小的记录;也不能接收到几十个字节就写一次磁盘)。

论坛徽章:
0
2 [报告]
发表于 2011-08-16 20:07 |只看该作者
我想不到特别的思路,觉得可以采用accept+fork的方式,对B,C,D...机器传送过来的数据,针对不同IP(预先分配的序号)分别接收,每个客户端传送的报文中需含有序号。

A主机的数据结构:

typedef struct recvNode
{
       int   dataSize;
       int   recvSize;
       int   reqNo;
       char dataBuf[dataSize+1];
       char  ipAddress[20];
       int   flag:1
}

A采用链表基础数据结构,先进行查找节点,遇到新的IP插入节点,初始flag=0,即数据未满,非新的节点copy缓冲区数据到dataBuf中,当recvSize达到dataSize时,flag=1,并将数据一次性写入磁盘.

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
3 [报告]
发表于 2011-08-17 09:01 |只看该作者
必须写到一个文件,不能B、C、D每个一个文件么?

论坛徽章:
0
4 [报告]
发表于 2011-08-17 09:12 |只看该作者
缓存每4K写一次,考虑是否能承受意外断电带来的数据丢失风险。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
5 [报告]
发表于 2011-08-17 09:20 |只看该作者
直接读写文件又怎么样呢?libc是有缓存的,怕丢数据就每隔一秒fsync呗。实在怕就用日志文件系统呗。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
6 [报告]
发表于 2011-08-17 10:48 |只看该作者
假设有一台机器A,有1G内存,另外若干台机器(B、C、D……)通过网络TCP向机器A传输数据,A机器把接收到的数 ...
liqingfang 发表于 2011-08-16 19:39

TCP连接有原子性,BCD每个连接自己报长度和顺序号即可。每个进程/线程按照自己的参数写文件,没有问题。

论坛徽章:
0
7 [报告]
发表于 2011-08-17 10:57 |只看该作者
本帖最后由 liqingfang 于 2011-08-17 11:00 编辑

回复 3# hellioncu

B,C,D ...分别写到自己的文件中

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
8 [报告]
发表于 2011-08-17 11:05 |只看该作者
可以简单点就能实现:

1、发送的数据都带上一个头,指示该数据的总长,可以与数据一起发送
2、收到数据头部后,即在文件中预留空间,有数据可立刻写入文件
3、收到别的机器发来的数据时,在预留空间后开始写

针对收到不完整的头的例外,直接关闭连接。在头很小的情况下,正常不应该发生的。

论坛徽章:
0
9 [报告]
发表于 2011-08-17 22:40 |只看该作者
其实TCP会保证你数据的完整性!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP