C++实现分布式文件解析系统
整个分布式文件解析系统一共有四个角色:任务分配服务器、文件解析服务器、工作站和管理平台。在一个大型的网络中,有若干个用户(即“工作站”)随机地通过“任务分配服务器”向若干个“文件解析服务器”提交文本文件。“文件解析服务器”将收到的文件解析后写入log文件中。“管理平台”负责以可视化的界面观察所有连接到的“任务分配服务器”和“工作站”的ip及工作状态。
任务分配服务器的作用是轮流地将来自“工作站”的文件传送请求转发到每个在线的“文件解析服务器”上,从而避免某个特定的“文件解析服务器”工作负载太重。“任务分配服务器”轮流给所有在线的“文件解析服务器”分配任务。轮流的原则是按每工作站每批轮流,不考虑每批文件的数量多少。当有“工作站”准备传送一批文件时,首先连接任务分配服务器,通知任务分配服务器有一批文件待传。任务分配服务器则把该工作站的IP和端口告诉选定的“文件解析服务器”,以便让“文件分析服务器”能主动和“工作站”连接,并完成该批文件传输。
ps:主动的含义是文件分析服务器主动通过 connect 连接工作站。“任务分配服务器”本身不接收或转发文件。工作站每次都是按批提交文件,一批文件的数量不等。
“文件解析服务器”每收到用户的一批文件后,就自动对该批文件进行“文件解析”。“文件解析”的功能是:
管理平台的作用是采用图形化的方式展示目前在线的工作站,文件分析服务器的工作状态。能展示工作站的IP,工作状态(传文件中或没有传文件)。能展示文件分析服务器的IP,工作状态(接收文件中,文件分析中,没有传文件,没有文件被分析)。当一个工作站或文件分析服务器宕机,能实时更新状态。
整个系统的工作流程如下图所示:
该项目源码在 https://githubcom/toMyLord/DistributedFileParsingSystem
src目录下包含 Server 类、 Client 类、 SpecificTime 类。 Server 类用于服务器初始化,监听 socket_fd ,接受来自客户端的连接请求,接收或发送信息,关闭套接字。 Client 类用于客户端初始化,连接服务器,与服务器进行全双工通信,关闭连接。 SpecificTime 类用于获取当前系统的时间,并以规定的格式返回一个 std::string 类型的字符串。上述三个类会被用于所有角色,因此以一个目录的形式单独放在所有角色所属目录外,通过CmakeListstxt将这些文件的编译相关性联系在一起,从而生成可执行文件。
该目录下为编译 TaskDistribution 所需要的专属文件。在当前目录下的src目录内,定义了 DistributionServer 类,该类内组合了DistributedFileParsingSystem/src目录下的 Server 类。实现 DistributionServer 类的目的是为了使用该类监听特定端口的所有网络连接,并将所有连接的客户端信息都存储在一个 std::vector 容器内。 DistributionServer 类的定义如下:
在 ClientNode 结构体内嵌套的 ClientInfo 结构体声明和定义在DistributedFileParsingSystem/src/serverh文件内, ClientInfo 结构体保存了连接到 server 的客户端的 sockaddr_in 、 socket_fd 以及ip信息。 ClientNode 结构体扩展了一个新的字段 client_state ,该字段用来描述客户端的传输状态。
通过 std::vector<ClientNode> 将所有连接的客户端信息都保存下来。每当有新的客户端连接,就使用 client_nodepush_back() 将信息保存在内存中。如果有已连接的客户端断开连接,需要用 find_if() 函数配合 lambda 表达式找到在 vector 中的迭代器,然后断开连接并删除 client_node 中对应的数据。具体过程如下:
TaskDistribution_maincpp是任务分配服务器可执行文件编译所需的主函数。在该文件内声明了两个 DistributionServer 类的实例 workstation_server 和 parsing_server ,一个 Server 类的实例 manager_server ,分别用来处理来自工作站、文件解析服务器、管理平台的连接。因为任务分配服务器只允许一个管理平台连接,因此管理平台选择 Server 类,因为可能会有大量工作站和文件解析服务器连接至任务分配服务器,因此选择 DistributionServer 来分别监听工作站和文件解析服务器的连接端口。
在主函数中,我选择使用 epoll ——IO多路复用技术来监听工作站、文件解析服务器和管理平台的连接请求,从而实现在单进程中对三个端口进行监听。
当有管理平台连接至任务分配服务器后,任务分配服务器就不再处理来自管理平台的连接请求,直到当前管理平台退出。
当有文件解析服务器连接至任务分配服务器后,任务分配服务器会将文件解析添加至就绪队列,等待来自工作站的请求。每当有工作站发出文件传输请求,就将处于就绪队列顶端的文件解析服务器出队列,并分配给当前工作站用来处理解析任务。处理完文件解析任务后,任务分配服务器会将文件解析服务器重新加入队列。
当工作站连接至任务分配服务器后,任务分配服务器会建立一个新的线程用来处理工作站发出的请求。当工作站发出文件解析请求后,该线程会将就绪队列顶端的文件解析服务器分配给工作站,并一直监控整个解析过程,直到解析完成,将文件解析服务器重新入队列。完成后此线程会重新监听来自工作站的解析请求,直到工作站断开连接,该线程就会消亡。如果工作站发出解析请求后,没有任务文件解析服务器就绪,那么任务分配服务器会每过1s检测一次是否有就绪的文件解析服务器(此处可以改进,将每秒轮询的方式改为等待时长者优先策略)。
该目录下为编译 TaskDistribution 所需要的专属文件。在当前目录下的src目录内,主要实现两个功能: 使用单例模式实现日志文件记录 、 使用状态模式实现文件解析服务器在等待状态和解析状态之间的切换 。
使用单例模式来实现日志记录的 RecordingLog 类的实例只会创建一次,从而避免创建多个日志类实例,造成写入混乱的情况。 RecordingLog 类会将特定信息以 filesteam 的方式写入文件中,具体被记录在日志文件中的信息包括接收来自工作站文件的时间、日期、工作站ip、工作站端口、文件名、文件前8个字节内容、文件总长度。该类的声明情况如下所示:
在本系统的FileParsing程序中,使用状态模式用来处理文件解析服务器的状态转换。文件解析服务器主要有两种状态——等待任务分配服务器发送解析文件请求状态和接受来自工作站的文件并完成解析,写入日志文件的状态。
在第一种状态下,文件解析服务器收到来自任务分配服务器的解析请求后,会将需要主动连接的工作站的ip及端口保存下来,并切换到第二种状态。
在第二种状态下,文件解析服务器根据保存的ip和端口主动连接工作站,连接完成后接收来自工作站的文件信息,解析后通过 RecordingLog 类中的 getLogInstance() 函数将解析后的结果写入日志文件,完成后会将解析完成情况回传给任务分配服务器,在任务分配服务器中,将该文件解析服务器重新添加到就绪队列。之后会主动切换到第一种状态,再次等待任务请求。
这部分程序使用了状态模式,使得文件解析服务器在等待分配任务状态及解析文件状态自动切换,从而保证了两种状态上的逻辑分离,具有非常好的封装性,并体现了开闭原则和单一职责原则:每个状态都是一个子类,如果需要增加状态就只需要增加子类,如果需要修改状态,就只需要修改一个子类即可完成,具有很高的扩展性。
该目录下为编译 WorkStation 所需要的专属文件。在当前目录下的src目录内,定义了 SendDirectory 类。通过该类,可以实现根据输入的一个目录,自动发送该目录下的所有文件。注意,该目录下不可再包含目录。
该目录下为编译 Managerplatform 所需要的专属文件。此目录可以使用QtCreater打开,但是编译还是需要根据DistributedFileParsingSystem/CMakeListstxt文件通过cmake编译。
该目录下的 ClientThread 类通过继承 QThread 类,实现在Qt中使用线程。在该部分程序运行时,就会创建一个 ClientThread 线程,用于与任务分配服务器建立连接,并不断接受来自任务分配服务发送的有关工作站及文件解析服务器的在线状态以及传输状态。每当有新的信息后,就通过Qt的槽机制,发送给 QDialog ,显示在界面中。
编译完成后会生成四个可执行文件:TaskDistribution、FileParsing、WorkStation、ManagerPlatform。
运行过程如下所示:
首先分别运行每个可执行程序,其中运行两个FileParsing程序(上线两个文件解析服务器):
在WorkStation程序下输入需要发送的文件目录:
可以在任务分配服务器的log中看到有新上线的文件解析服务器,同时在管理平台也可以看到对应的文件解析服务器。我们通过工作站连续发送三次文件。
实现了整个分布式任务解析服务器框架,整个项目可以正常实现需求功能。
缺陷:任务分配服务器存在不能正常处理所有连接的正常close。
在任务分配服务器处新增了心跳包机制——任务分配服务器会每隔5s向所有连接在线的文件解析服务器和工作站发送心跳包,文件解析服务器和工作站在收到心跳包后,也会主动回应心跳。通过心跳包机制可以很好的处理来自其他连接的断开情况。同时新增了在管理平台退出后,任务分配服务器可以重新接受来自管理平台的连接。
蛟云DF系列是亿万克推出的全新一代分布式文件存储系统,具有高扩展、多协议、高性能、高可靠的特点,提供POSIX、NFS、SMB/CIFS、FTP等丰富的文件服务,满足数字化时代海量数据的存储需求,适用于人工智能(AI)、自动驾驶、高性能计算(HPC)、生命科学、影视渲染等场景。感兴趣的话点击此处,免费了解一下
服务器必须具有一定的“可扩展性”,这是因为企业网络不可能长久不变,特别是在当今信息时代。如果服务器没有一定的可扩展性,当用户一增多就不能胜任的话,一台价值几万,甚至几十万的服务器在短时间内就要遭到淘汰,这是任何企业都无法承受的。为了保持可扩展性,通常需要在服务器上具备一定的可扩展空间和冗余件(如磁盘阵列架位、PCI和内存条插槽位等)。
亿万克作为中国战略性新兴产业领军品牌,拥有中国第一、世界前二的行业领先技术,致力于新型数据中心建设,构筑云端安全数字底座,为客户提供集产品研发、生产、部署、运维于一体的服务器及IT系统解决方案业务,所有产品和技术完全拥有自主知识产权,应用领域涵盖云计算、数据中心、边缘计算、人工智能、金融、电信、教育、能源等,为客户提供全方位安全自主可控技术服务保障。
分布式系统一定是由多个节点组成的系统。
其中,节点指的是计算机服务器,而且这些节点一般不是孤立的,而是互通的。
这些连通的节点上部署了我们的节点,并且相互的操作会有协同。
分布式系统对于用户而言,他们面对的就是一个服务器,提供用户需要的服务而已,
而实际上这些服务是通过背后的众多服务器组成的一个分布式系统,因此分布式系统看起来像是一个超级计算机一样。
集群是指在几个服务器上部署相同的应用程序来分担客户端的请求。
它是同一个系统部署在不同的服务器上,比如一个登陆系统部署在不同的服务器上。
好比多个人一起做同样的事。
集群主要的使用场景是为了分担请求的压力。
但是,当压力进一步增大的时候,可能在需要存储的部分,比如mysql无法面对大量的“写压力”。
因为在mysql做成集群之后,主要的写压力还是在master的机器上,其他slave机器无法分担写压力,这时,就引出了“分布式”。
分布式是指多个系统协同合作完成一个特定任务的系统。
它是不同的系统部署在不同的服务器上,服务器之间相互调用。
好比多个人一起做不同的事。
分布式是解决中心化管理的问题,把所有的任务叠加到一个节点处理,太慢了。
所以把一个大问题拆分为多个小问题,并分别解决,最终协同合作。
分布式的主要工作是分解任务,把职能拆解。
分布式的主要应用场景是单台机器已经无法满足这种性能的要求,必须要融合多个节点,并且节点之间的相关部分是有交互的。
相当于在写mysql的时候,每个节点存储部分数据(分库分表),这就是分布式存储的由来。
存储一些非结构化数据:静态文件、、pdf、小视频 这些也是分布式文件系统的由来。
分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。
正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。
扩展资料分布式系统系统优点
1、经济:微处理机提供了比大型主机更好的性能价格比
2、速度:分布式系统总的计算能力比单个大型主机更强
3、固有的分布性:一些应用涉及到空间上分散的机器
4、可靠性:如果一个机器崩溃,整个系统还可以运转
5、渐增:计算能力可以逐渐有所增加
—分布式系统
1简介
分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。分布式文件系统的设计基于客户机/服务器模式。一个典型的网络可能包括多个供多用户访问的服务器。另外,对等特性允许一些系统扮演客户机和服务器的双重角色。例如,用户可以“发表”一个允许其他客户机访问的目录,一旦被访问,这个目录对客户机来说就像使用本地驱动器一样。
当下我们处在一个互联网飞速发展的信息 社会 ,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化。在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集、数据存储、数据搜索、数据共享、数据传输、数据分析、数据可视化等一系列问题。
传统存储在面对海量数据存储表现出的力不从心已经是不争的事实,例如:纵向扩展受阵列空间限制、横向扩展受交换设备限制、节点受文件系统限制。
然而分布式存储的出现在一定程度上有效的缓解了这一问题,之所以称之为缓解是因为分布式存储在面对海量数据存储时也并非十全十美毫无压力,依然存在的难点与挑战例如:节点间通信、数据存储、数据空间平衡、容错、文件系统支持等一系列问题仍处在不断摸索和完善中。
2分布式文件系统的一些解决方案
Google Filesystem适合存储海量大个文件,元数据存储与内存中
HDFS(Hadoop Filesystem)GFS的山寨版,适合存储大量大个文件
TFS(Taobao Filesystem)淘宝的文件系统,在名称节点上将元数据存储与关系数据库中,文件数量不在受限于名称节点的内容空间,可以存储海量小文件LustreOracle开发的企业级分布式系统,较重量级MooseFS基于FUSE的格式,可以进行挂载使用MogileFS
擅长存储海量的小数据,元数据存储与关系型数据库中
1简介
MogileFS是一个开源的分布式文件系统,用于组建分布式文件集群,由LiveJournal旗下DangaInteractive公司开发,Danga团队开发了包括 Memcached、MogileFS、Perlbal等不错的开源项目:(注:Perlbal是一个强大的Perl写的反向代理服务器)。MogileFS是一个开源的分布式文件系统。
目前使用 MogileFS 的公司非常多,比如国外的一些公司,日本前几名的公司基本都在使用这个
国内所知道的使用 MogileFS 的公司有托管网站 yupoo又拍,digg, 土豆, 豆瓣,1 号店, 大众点评,搜狗,安居客等等网站基本很多网站容量,都超过 30T 以上。
2MogileFS特性
1) 应用层提供服务,不需要使用核心组件
2)无单点失败,主要有三个组件组成,分为tracker(跟踪节点)、mogstore(存储节点)、database(数据库节点)
3)自动复制文件,复制文件的最小单位不是文件,而是class
4)传输中立,无特殊协议,可以通过NFS或HTTP实现通信
5)简单的命名空间:没有目录,直接存在与存储空间上,通过域来实现
6)不用共享任何数据
3MogileFS的组成
1)Tracker--跟踪器,调度器
MogileFS的核心,是一个调度器,mogilefsd进程就是trackers进程程序,trackers的主要职责有:删除数据、复制数据、监控、查询等等这个是基于事件的( event-based ) 父进程/消息总线来管理所有来之于客户端应用的交互(requesting operations to be performed), 包括将请求负载平衡到多个"query workers"中,然后让 mogilefs的子进程去处理
mogadm,mogtool的所有操作都要跟trackers打交道,Client的一些操作也需要定义好trackers,因此最好同时运行多个trackers来做负载均衡trackers也可以只运行在一台机器上,使用负载均衡时可以使用搞一些简单的负载均衡解决方案,如haproxy,lvs,nginx等,
tarcker的配置文件为/etc/mogilefs/mogilefsdconf,监听在TCP的7001端口
2)Database--数据库部分
主要用来存储mogilefs的元数据,所有的元数据都存储在数据库中,因此,这个数据相当重要,如果数据库挂掉,所有的数据都不能用于访问,因此,建议应该对数据库做高可用
3)mogstored--存储节点
数据存储的位置,通常是一个HTTP(webDAV)服务器,用来做数据的创建、删除、获取,任何 WebDAV 服务器都可以, 不过推荐使用 mogstored mogilefsd可以配置到两个机器上使用不同端口… mogstored 来进行所有的 DAV 操作和流量,IO监测, 并且你自己选择的HTTP服务器(默认为 perlbal)用来做 GET 操作给客户端提供文件
典型的应用是一个挂载点有一个大容量的SATA磁盘 只要配置完配置文件后mogstored程序的启动将会使本机成为一个存储节点当然还需要mogadm这个工具增加这台机器到Cluster中
配置文件为/etc/mogilefs/mogstoredconf,监听在TCP的7500端口
4基本工作流程
应用程序请求打开一个文件 (通过RPC 通知到 tracker, 找到一个可用的机器) 做一个 “create_open” 请求
tracker 做一些负载均衡(load balancing)处理,决定应该去哪儿,然后给应用程序一些可能用的位置。
应用程序写到其中的一个位置去 (如果写失败,他会重新尝试并写到另外一个位置去)
应用程序 (client) 通过”create_close” 告诉tracker文件写到哪里去了
tracker 将该名称和域命的名空间关联 (通过数据库来做的)
tracker, 在后台, 开始复制文件,知道他满足该文件类别设定的复制规则
然后,应用程序通过 “get_paths” 请求 domain+key (key == “filename”) 文件, tracker基于每一位置的I/O繁忙情况回复(在内部经过 database/memcache/etc 等的一些抉择处理), 该文件可用的完整 URLs地址列表
应用程序然后按顺序尝试这些URL地址 (tracker’持续监测主机和设备的状态,因此不会返回死连接,默认情况下他对返回列表中的第一个元素做双重检查,除非你不要他这么做)
1拓扑图
说明:1用户通过URL访问前端的nginx
2nginx根据特定的挑选算法,挑选出后端一台tracker来响应nginx请求
3tracker通过查找database数据库,获取到要访问的URL的值,并返回给nginx
4nginx通过返回的值及某种挑选算法挑选一台mogstored发起请求
5mogstored将结果返回给nginx
6nginx构建响应报文返回给客户端
2ip规划
角色运行软件ip地址反向代理nginx1921681201存储节点与调度节点1
mogilefs1921681202存储节点与调度节点2
mogilefs1921681203数据库节点
MariaDB1921681204
3数据库的安装操作并为授权
关于数据库的编译安装,请参照本人相关博文http://wangfeng7399blog51ctocom/3518031/1393146,本处将不再累赘,本处使用的为yum源的安装方式安装mysql
4安装mogilefs 安装mogilefs,可以使用yum安装,也可以使用编译安装,本处通过yum安装
5初始化数据库
可以看到在数据库中创建了一些表
6修改配置文件,启动服务
7配置mogilefs
添加存储主机
添加存储设备
添加域
添加class
8配置1921681203的mogilefs 。切记不要初始化数据库,配置应该与1921681202一样
9尝试上传数据,获取数据,客户端读取数据
上传数据,在任何一个节点上传都可以
获取数据
客户端查看数据
我们可以通过任何一个节点查看到数据
要想nginx能够实现对后端trucker的反向代理,必须结合第三方模块来实现
1编译安装nginx
2准备启动脚本
3nginx与mofilefs互联
查看效果
5配置后端truckers的集群
查看效果
大功告成了,后续思路,前段的nginx和数据库都存在单点故障,可以实现高可用集群
0条评论