RFID与MongoDB融合的分布式云仓储管理系统
2021-01-19陈振武兰添才郑汉垣
陈振武,杨 洋,兰添才*,郑汉垣
(1.龙岩学院 数学与信息工程学院,福建 龙岩 364012;2.龙岩学院 大数据挖掘与应用福建省重点实验室,福建 龙岩 364012;3.福建钰辰微电子有限公司,福建 龙岩 364012;4.龙岩学院 传播与设计学院,福建 龙岩 364012)
1 概 述
大数据、云计算、分布式存储系统、区块链等新技术的提出,不断创造出独特的新互联网模式,同时也向人们展示了去中心化分散基础设施建立的模型。基于多元化的现代仓储系统也逐渐得到研究与重视,现代化的仓储区域规划与管理的智能化程度直接影响仓储作业效率和储存能力[1],这些现象在带来海量数据频繁存取问题[2]的同时,随着仓储企业规模的不断扩大,也出现了物资可能会存放于不同部门、不同地域,尤其是多层级仓库的货品管理及各组织的仓库资源账目不能及时掌控库存的情况,导致产生大量繁琐数据、数据不统一、无法及时统计分析,造成仓储企业管理效率低下的现象[3]。为了实现高效、智能化的企业仓库管理,许多学者针对智能化仓储管理系统应用进行了深入研究[4]。复旦大学的许嘉勋提出了一种基于云数据库的企业资产管理,并以MongoDB数据库为例,分析了MongoDB数据库建模的可行性,设计并实现了一个基于MongoDB数据库的高可靠、高扩展的分布式企业资产管理系统[5]。
在基于Web的架构中,数据库难以实现横向扩展[6],非关系数据库中利用查询语言对数据进行查询没有行的概念,数据在存储的时候没有固定的键值模式,一般都是通过文档的形式进行存储[7]。朱爱华等针对经典的仓储信息服务系统大都使用关系型数据库,结合前端交互技术以及非关系型数据库MongoDB来搭建Web服务,并通过性能测试证明了该架构比传统的数据库操作在处理速度和资源占用上具有更好的性能优势[8]。文献[9]也证明了在非关系型数据库NoSQL中引入Web的架构系统,可以利用NoSQL优势来弥补关系型数据库的不足。
该文在充分研究分析非关系型数据库MongoDB在分布式存储方面的特性,利用前端开源框架Angular设计实现软件逻辑操作功能;通过将Angular与RFID技术融合设计实现一种分布式智能仓储管理系统,并利用基于MongoDB云数据库的高可用性构架特性将仓储企业的各分支机构的数据存储系统整合起来建立一个私有云,解决对异地分布的仓储的物资、设备容量不断扩容的需求与仓储管理运营成本之间的矛盾,旨在为多站点多仓库共享数据的仓储系统Web管理应用提供可扩展的高性能数据存储解决方案。
2 系统总体架构
针对建立数据仓库时存在的系统需求不断变化、语义断层以及数据仓库改动难、代价大等问题,建立数据仓库采用分层架构是一种很常见的模式,也叫N层架构[10]。该文提出一种4层数据仓库体系结构模型,包括表述层、控制层、业务逻辑层、数据库物理层。系统分层结构示意参见图1。
图1 系统分层结构
3 系统云架构
3.1 系统数据库分区建立
建立系统云架构,首先要解决的就是需对大量分散的数据进行分区存储的问题,即将数据拆分并分散储存在不同的服务器上。
该文利用MongoDB能够支持数据自动分区的特性,将数据库中的数据按相关属性划分成若干数据组,并将这些数据组分散到若干较大的分区中,每个分区负责总数据的一部分。系统主控程序中在对数据库进行数据分区之前先建立两个路由进程,一个是用于对多个分区的数据库进行路由探测并提出连接申请的进程Mongo_sq;另一个是用于系统在没有数据分区(隐藏数据分区的细节)的时候提供给客户端连接路由的进程Mongo_pt,可以实现在不修改系统程序的情况下对系统分布的节点进行增加或删减。
具体的做法是在对系统进行数据分区时,从数据属性集选择某个具有代表性的字段作为一个共享“键”(Shard key),该“键”的键值即作为数据分区的主要依据,并对这些键进行编号(如Shardkey_01,Shardkey_02,……)。如可以使用“仓库ID”来定义各仓库、产品存储位置、库位设置等数据库或数据表的共享“键”,在此基础上建立不同数据的分区,并存放于不同的服务器或本地计算机上,当系统查询“仓库ID”如果是属于“物资库存管理”时即直接将该共享“键”有针对性地发送到“物资库存管理”数据分区所在的服务器或本地计算机上,同样,如果RFIDI设备扫描到的产品隶属于某个仓库,就直接将该产口的相关信息发送到对应的分区数据库中。
3.2 云数据库系统用例
云数据库系统用例(包括普通用户和管理员用户)参见图2。
图2 云数据库系统用例
普通管理员可以按照一定的需求条件申请所需的云数据库(如果是企业外的用户需缴纳一定的费用才能获得),通过系统自动分配成功后,提供给相应的普通管理用户对相应云数据库访问的地址、端口及数据库名称等信息;相应地,如果普通管理员放弃对该数据库的使用权,系统会根据自动对相关数据进行处理后回收该云数据库所占用资源。
超级管理员通过硬件设备的管理功能子模块、对普通管理员的管理子模块以及对云数据库的管理操作等对云数据库进行访问,包括设置绑定终端节点的ip地址,使得仅被绑定的ip才有权访问选定云数据库、为普通管理员用户设定初始化的用户名、登录条件及启/停云数据库服务等功能。普通管理员对云数据库的操作功能则主要包括通过启/停云数据库、更改用户信息、变更数据库访问权限、日常功能维护以及通过仓库管理系统对商品的信息采集与管理等功能模块对云数据库进行访问。
3.3 系统高可用性架构
系统高可用性架构(Replica Set)是MongoDB系统为了构建具有自动容错及恢复功能的一项非常实用的高可用性方案[11]。该文提及的系统设计建立的基础思想是,将一些位于同一地点或不同地点的服务器集合起来建立业务服务器云,数据库层采用分布式的物理结构进行云架构,系统云架构示意参见图3。
图3 系统云架构示意
系统依据数据库的规模设定一个或多个数据分区并配置相应的能够表明数据位于哪个分区的共享数据元素“键”的拷贝,这样就构成了一个Replica Set节点,每个节点可进一步分为一个或多个子节点,但每个节点须持有相同数据的拷贝。同时,还需定义主从节点,即一个节点为主节点,其他为从节点,且这些节点均需具有系统重构功能,即如果主节点出现故障,可选择一个从节点自动承担主节点的工作。
每个节点服务器需配置—个或多个路由器提出连接申请的进程Mongo_sq路由器提供给客户端路由申请服务,并将请求分发到相应的数据分区服务器上。分区服务器配置内容主要包括服务器名称、IP地址、端口三个方面。
其中端口配置的内容比较复杂,主要应包括:
(1)整个系统所有分区共享“键”(Shard key)访问端口的分配(各个“键”可分配同一端口),该“键”的键值即作为数据分区的主要依据,并对这些键进行编号(如Shardkey_01,Shardkey_02,……);
(2)用于访问没有数据分区的时候提供给客户端连接路由的Mongo_pt端口;
(3)用于对多个分区的数据库进行路由探测并提出连接申请的进程Mongo_sq;
(4)服务器配置详细过程就不赘述。
3.4 分区数据库操作的均衡问题
对MongoDB数据库操作必然会存在对各节点的文档访问操作的均衡性问题,而且须对这个均衡问题进行协调控制,否则系统很容易因为对某个节点文档的高密度访问而造成数据拥堵问题。
利用文献[12]提出的基于数据操作的频率(FODO)改进的均衡算法设计,以解决对数据库操作的均衡问题,算法可描述如下:
(1)初始化。
设集群有p个节点,有d个文档块被集合在一起形成由MongoDB自动分隔的集群文档;
(2)定义变量。
Inti=1,2,…,n;
Int Bi,Oi,Ii,Fi,Ci,DOi,DOi,λ;
Int SUM_DOi,SUM(SUM_DO);
//Bi是文档块数,Oi、Ii、Fi、Ci分别存放对文档块的操作频率、插入操作频率、查询操作频率和更改操作频率;DOi表示每个节点中文档块数据某个操作的频率;SUM_DOi存放每个节点中所有文档块数据的所有操作频率之和;λ表示调节负载均衡过程中分配各节点各文档块数据操作的比重参数,SUM(SUM_DO)存放整个集群分区各个节点中数据操作频率之和[13]。
(3)计算各节点各文档块数据操作频率。
(4)计算各节点各文档块数据所有操作频率。
(5)计算带有均衡修正系数λ(λ>1)的各节点各文档块数据所有操作频率之和。
(6)计算整个分区的操作频率可以用每个节点中所有文档数据的操作频率之和。
其中λ是为了调整插入操作与查找、修改操作的均衡关系参数。由于MongoDB对数据的访问与修改时会对前一次查询过或修改过的数据进行记忆并将其保存到缓存中,当下一次需对这些访问过的数据查询或修改时相当于访问的是本地缓存的数据;MongoDB对每个分区的操作会提供一个包含分别承担数据的写、读负载的primary和secondary两个节点的replica set,使数据最大限度被利用。因此,MongoDB系统对数据插入操作负载的影响要比读和写操作负载的影响要大得多,尤其是每当在进行插入数据操作时,每一个数据块所在的节点中的数据信息均会造成负载不均衡,而当不均衡的数据量达到一定程度时,系统的数据迁移阈值会触发启动,对不均衡的现象进行调节,在这个过程中,系统资源被极大地浪费[14]。因此,为平衡插入与读写操作的比重,在计算插入操作频率中增加一个系数调节参数λ(λ>1)[15],确保节点负载的均衡。
4 系统功能分析
4.1 系统功能模块
系统主要由统计分析、库存管理、记录查询、产品管理、RFID读头管理、仓库管理、系统设置七大部分组成。系统通过B/S(Browser/Server)结构进行布置,物料或货品的基础数据和系统对数据进行管理的程序可分别运行于不同的服务器,系统终端的控制程序可以同时运行于不同的微机上。
(1)统计分析:用户对近期出库入库趋势及流动物资总量有一个直接的了解,如库存总量、入库总量、出库总量;
(2)库存管理:包括物资出库、入库、调拨、移库、报损、盘点等功能;
(3)记录查询:针对物资操作后的记录进行查询,通过不同的搜索条件聚合查询,快速准确地定位到用户需要的记录信息;
(4)产品管理:主要对批量标签绑定商品的管理,设置了产品型号管理和商品添加功能,可以实现对单独一个型号的产品管理;
(5)RFID读头管理:依据不同环境下对不同的读着性能进行调整设置;
(6)仓库管理:每个仓库中包含了多个门,门与读头属于对应关系,以表明其出库还是入库属性,仓库内也有很多个库位,库位也包含了库位容量、库位属性等属性的设置、修改与绑定等功能;
(7)系统设置:超级管理员才有操作权限,可以添加普通管理员,修改账号信息等。
4.2 顶层数据流图
顶层数据流主要描述管理员之间的角色数据关系,不同角色对应操作不同功能模块,并将操作结果数据存储到云端数据库。管理员之间的数据流(顶层)参见图4所示。
图4 管理员之间的数据流(顶层)
4.3 第二层数据流图
描述不同管理员与对应功能模块的数据流向关系。超级管理员无权限限制,包括硬件信息管理、出库、入库、调拨、移库、报损、盘点操作及记录查询、库存查询、对产品产品类型的定义、添加商品等功能。而普通管理员主要针对逻辑操作及查询功能,没有进行硬件信息管理的权限。管理员与对应功能模块的数据流(第二层)参见图5。
图5 管理员与各模块的数据流(第二层)
5 系统设计与实现
5.1 数据库设计
数据库的设计充分考虑业务场景、数据读写频率、安全一致性等方面的需求,以及主节点服务器出现系统崩溃后能够迅速切换到其他节点,采用MongoDB分布式副本集架构为基础,共设计了6张表:用户信息表、仓库表、商品信息表、仓库门信息表、仓库位信息表、商品库存表。
(1)用户信息表:用户名、用户密码、用户ID、用户角色、用户邮箱;
(2)仓库表:仓库ID、仓库名称、管理员、仓库地址、属性;
(3)商品信息表:商品序列号、编号、名称、生产日期、商品EPC码、商品NFC码、型号、类别、图片地址;
(4)仓库门信息表:门ID、名称、类型,库位ID、库位名称、库位规模;
(5)仓库位信息表:所属仓库、仓库位ID、管理员、仓库地址、仓库位规模、当前存放量;
(6)商品库存表:商品序列号、编号、名称、入库时间、商品EPC码、商品NFC码、型号、类别,仓库编号、仓库名称、库位编号、库位名称等。
5.2 前端访问数据库
前端使用Angular封装的httpClient模块,在ng-alain中又被封装成更为便捷的httpClient方法,可以很方便地自动添加请求头并处理返回的对应的数据格式,其实质上仍然还是使用http方法请求数据,返回的数据用rxjs中的observable订阅处理。该文的数据接口用postman软件进行梳理和测试、调试,最后将所有项目打包部署在服务器上。为了数据安全,运行中的数据请求应用改为https请求。
5.3 功能模块实现
着重介绍登录,RFID读头管理,库存管理中的入库、出库、调拨、移库、报损、盘点,并以登录功能实现主要代码及登录主界面、RFID读头管理主界面截图(其他模块的界面图略)为例。
(1)登录模块。
登录模块主要是在用户输入时进行了表单验证和登录失败时提示信息,并且在登录成功后显示用户头像、用户邮箱等信息。在Session Storage中存储用户角色以及携带的Token,Token精度设置在秒,有效期为两个小时。用户登录主界面参见图6,实现代码可简单表述如下(其他功能模块的实现代码详略)。
//清空路由复用信息
this.reuseTabService.clear(); //设置用户Token信息
this.tokenService.set(res);
//重新获取StartupService内容,信息一般都会受当前用户授权范围而影响
const user={
name:res.name,//avatar:res.avatar,avatar:'./assets/tmp/img/avatar.jpg',userId:res.id,
};
this.settingsService.setUser(user);this.startupSrv.load().then(()=>{let url=this.tokenService.referrer.url||'/';
if (url.includes('/passport')) url='/';
this.router.navigateByUrl(url);
});
}
图6 用户登录主界面
(2)RFID读头管理。
读头设置需要先获取模式等相关硬件参数,包括读写器硬件属性信息、射频输出功率、天线、蜂鸣器、标签过滤规则等,可依据不同的场景的需要调整读头配置。读头详细功能设置参见图7。
图7 RFID读头详细设置
(3)物资入库。
利用数据实时传输通信功能的ngx-mqtt插件,获取仓库/门主题并将接收到的数据存入数据库提供给查询系统,将得到相应的商品信息转换成用户需要的格式展示在表格中,并在表格的底部显示汇总统计信息。操作员确认后点击入库按钮、填写入库单号、选择库位、提交入库。
(4)物资出库。
商品出库功能先进行扫描然后过滤重复的商品信息,填写出库单号,执行出库。与入库操作不同的是,出库时扫描的商品是在库存里查找,入库的信息则是在商品信息库中查找。
(5)物资调拨。
调拨是物资从一个仓库转移到另一个仓库的过程,拆分开就是先执行出库再入库,在执行调拨时需要选择目的仓库,在目的仓库入库时选择库位就完成了整个调拨过程。
(6)物资移库。
移库与调拨是不同的概念,是在同一个仓库内不同的库位周转的过程。在确认物资信息正确之后选择新库位与旧库位,执行移库操作。
(7)物资报损。
在物资使用或者存放过程中会出现损坏情况,报损功能为了及时分离这些损坏商品,功能流程与出库一致。找出损坏商品,读头扫描,执行报损,数据库实时更新报损数据,并做统计。
(8)物资盘点。
按照仓库管理的要求,需要进行不定期的盘点。前端网页按照需要盘点的物资条件查询到指定商品,生成盘点信息单,发送到手持机,手持机拉取盘点单,在指定库位进行扫描,将扫描结果进行对比,将结果展示给操作员。
(9)入库记录查询。
记录查询主要是搜索条件比较多,接口也相应地做了聚合查询。可以单条查询,也可以多条。正因为搜索条件较多,为了得到更好的用户体验也加上了清除功能,用来清除表单中已经有的值,方便重新输入。查询结果中,查看按钮对应每条数据的详情单,可以选择查看并打印。
(10)调拨记录查询。
调拨与盘点、报损、移库搜索条件均为相应单号和操作时间,搜索结果以单号分类,点击单条单跳转到相应的单详情页,所有的详情单提供导出pdf功能。
(11)硬件信息操作。
在项目中是没有出现过硬件信息这条的,但是因为从仓库到读头、库位、门这些都属于硬件范畴。而且规划好了之后一般是不会去修改的,所以就把它们统一划分到硬件范畴,但是功能还是独立的,也设置了单独的功能页面。
(12)人员管理。
人员管理主要针对密码和邮箱的修改。这是只有超级管理员才有的权限。如果需要添加超级管理员账号需要联系我们在数据库添加,这也保证了一定程度的数据安全。
6 结束语
通过非关系数据库系统建立分布式云存储系统,针对在多点多级仓储管理系统所涉及的复杂应用管理,系统结合RFID技术对物资二维码标签进行唯一性的识别,以使系统管理的可靠性、稳定性得到有力的保证。系统综合考虑仓储业务多元化发展的需求,探索了在同构系统中将分布式数据库与云存储原理结合在仓储企业的应用,对于异地性、分布式的仓储企业的大规模物品管理具有一定的借鉴意义,系统也可拓展应用于其他具有分布式需求的企业仓储管理。下一步将从两个方面进一步开展研究:(1)在异构系统中对信息查询访问、数据库之间的数据迁移、数据归并、所定义的数据结构等方面的性能评价还需做进一步的探索与研究;(2)该文只是涉及设计实现分布式仓储管理系统的关键功能,但对各不同仓储系统的权限、角色、功能等的可扩展性还需进一步研究。