文章目录:
- 1、两台linux服务器想共享一个磁盘分区,怎么做?
- 2、有什么软件能通过局域网来让多台电脑分享CPU和内存等硬件资源?
- 3、tbus_888是什么文件,为什么莫名其妙出现在了c盘里还占了12个g的内存
- 4、在并行计算中,不同计算机之间需要数据通信,我想实现的是:多台计算机共享服务器内存中的数据
- 5、web服务器之间如何做到内存共享
- 6、共享内存实现原理
两台linux服务器想共享一个磁盘分区,怎么做?
1、首先打开电脑的虚拟机,再打开物理机的虚拟网卡。
2、然后选择虚拟机的连接方式为nat,再开启两台Linux虚拟机,然后检查ip地址。
3、然后更改两台虚拟机的ip地址,在设置ip地址为手动。
4、然后配置ip地址,再重新启动网卡服务。
5、然后查看ip地址的更改情况,再用ping命令进行检查连通性。
有什么软件能通过局域网来让多台电脑分享CPU和内存等硬件资源?
CPU是可以的,以前在ibm工作的时候,IBM是有这种软件的,每个员工可以让自己电脑空闲的时候进行一定的计算工作,但是,这种方式仅限于对于“实时性”“时效性”要求很低的计算,偏向于一些科研性质的计算,比如,类似于一些比如气候模拟计算等,而不适合进行商用级的和你所说的渲染工作,因为商用级别的处理牵扯到时效性和客户体验度,而渲染这个不是纯粹的cpu计算,渲染还有2d和3d的工作,这是gpu的事情,商用和科学计算都是不涉及到图形的,即便是英伟达的telsa计算卡,在服务器上面都是进行纯计算,而不是3d渲染。
内存,这个没意义,因为即便是我存储到本地的硬盘上面,速度也比你先通过网络,然后存到别人的计算机内存里面块,因为硬盘就算是hdd读写也差不多150,而网络,就算是千兆网,峰值只有125,而且,内存读写访问关系来说,你这样做,关系是,先从本地硬盘读取到本机内存,然后通过网络传输到其他的电脑内存,你需要访问的时候,再通过网络传输回来。
硬盘,这个有,只要你网速够快,windows用samba共享就可以。
你这想法挺好,但“通用的硬件资源共享”是没有的,因为每个程序的数据不一样,而且即便仅仅针对一个特定的程序,实现也是有难度的,因为在实现的时候,通常是将一个计算进行均分,比如分成5份,这个时候,有一个突出的问题,就是各计算节点的处理情况,比如说,ABCDE五个,但是只要有一个节点处理速度慢,那么整个计算进度就会因为这一个节点而延误,这也是为什么目前的多cpu,多显卡都是基于相同的型号,而且你这个想法是基于网络,人家是通过专用数据总线直连,什么意思呢,网络的方式会有“延时”“丢包”的问题,而且网络传输的数据包是要经过逐层处理解释,这还有一个很长的过程,这起码是几十到几百毫秒,直连的方式完全没有这个问题,直连的访问延时是几十纳秒。
最后,不要说这种方式,就说最简单的,目前很多游戏连本地的双显卡都不支持,只能用到一块,想做到“网间通用硬件资源共享”,这非常难,你所说的“国外有人通过硬件连接实现多台电脑组成一个超级电脑”,根据我多年从业经验,这种超级电脑要么只能处理“”特定格式“的数据,要么仅能进行理论性能测试,对于民用和商用毫无价值。
tbus_888是什么文件,为什么莫名其妙出现在了c盘里还占了12个g的内存
Tbus简介
Tbus是tsf4g(Tencent ServiceFramework for Game,腾讯游戏服务框架)中的基础组件之一,主要的目的是为上层业务提供统一的线程或进程间通信接口,屏蔽本地进程间通信以及远程进程通信的细节,让开发人员可以集中精力关注业务逻辑,是tsf4g重要组成部分。
Tbus原理
Tbus基于共享内存构建无锁双通循环消息队列,发送的双方通过专用的读写队列完成数据收发,实现本地进程通信或者远程进程间通信。通信双方使用的两个队列称之为tbus通道(channel),每一组通讯的双方就需要有一个tbus通道。如下是一组tbus通道的图例描述。
进程A或B启动后,通过tbus API绑定到对应的通道,使用通道的两个消息队列进行收发数据,而不用关注对方的部署位置。
Tbusd
如果A和B同部署于一台物理设备,与上图描述一致。如果A、B部署于不同设备之上则需要tbusd服务进程完成消息中转。通信关系如下图。
进程A发送消息后,消息被存储在Host A的发送队列中,部署于Host A的tbusd发现队列中存在消息,则从队列中把消息取出,通过tcp发送Host B上。Host B上的tbusd接收到消息后,把消息写入本地的接收队列,以供进程B读取。
为了能完成通信,Tbus还有以下几个特点:
通信双方具备全局唯一的tbus通信地址,该地址是一个点分十进制的字符串,与IP地址类似,总长度为32bit,分为4段,每段bit位数可以自定义,总长度不得超过32bit。例如:128.1.100.1,5.0.200.1。
Tbus通道以及消息是存储在共享内存中,必须要使用相应的工具提前创建,进程才能绑定和使用。而当业务进程异常退出后,由于消息是存储在共享内存中,只要不主动清理共享内存、重启服务器或损坏共享内存,通道中的消息就不会丢失。
Tbus通道为每一个消息都会分配一定时间内唯一的一个序列号,当消息需要跨物理服务器中转时,远端的tbusd会针对该序列号的消息进行确认,如果本地tbusd未收到确认,该消息则会重传。
当tbus通道被消息写满后(例如对端服务器死机,本地进程仍继续发送消息),则无法再往通道中写入消息,该异常需要业务自己处理。
GCIM
一台服务器可以有诸多的通信关系,每一条tbus通道就是最小的通信单元,每条通道都有自己的配置区域,保存着通道大小,通道地址以及读写指针等,一台服务器上所有配置信息汇聚起来就是全局通道信息表(globalchannel information map, GCIM),一台服务器仅需要一份。管理GCIM的工具是tbusmgr。管理关系如下:
GRM
如果一台服务器不需要和其他远程服务器通信,则使用GCIM就能完成所有工作。当两台服务器需要使用tbus进行通信时,为了完成通信,除了启动tbusd服务进程之外,还需要建立一份通信配置,称之为全局路由表(globalroute map,GRM),用于说明哪些通道的消息需要中转。GRM也是保存在共享内存中,每一台机器只需要一份,管理GRM的工具为trelaymgr。
Tbus配置与工具
1.Tbusmgr 与GCIM
Tbusmgr是用于创建,维护GCIM的重要命令行工具。创建GCIM共享内存信息需要依赖tsf4g规范的xml配置文件。Tbusmgr可以根据xml文件的信息对GCIM进行增删改查等所有操作。Tbusmgr.xml配置文件仅包含两部分,一部分是公共参数的设定,例如通信地址模板设定,共享内存key的设定。一部分是对tbus通道(channel)的配置,每一组通信关系就需要一份。简单tbusmgr.xml说明如下:
TbusGCIM
!-- 十进制点分表示法表示的通信地址模版 --
AddrTemplet8.8.8.8/AddrTemplet
!-- GCIM共享内存key --
GCIMShmKey1000/GCIMShmKey
Channels
Priority8/Priority
!-- 通道两端进程的通信地址,使用点分法表示 --
Address0.0.1.1/Address
Address0.0.3.1/Address
!-- 对于出现在配置中的第一个进程而言,SendSize,RecvSize分别表示此进程相关发送,接受数据队列的大小。由于两个进程是对等的,因此第一个进程的发送队列大小(SendSize)就是第二个进程的接受队列大小(RecvSize) --
SendSize20480000/SendSize
RecvSize20480000/RecvSize
Desctcmcenter and itstconnd/Desc
/Channels
Channels
Priority8/Priority
Address0.0.1.1/Address
Address0.0.2.1/Address
SendSize20480000/SendSize
RecvSize20480000/RecvSize
Desctcmcenter and itscenterd/Desc
/Channels
/TbusGCIM
上述配置描述了:
通信地址32bit分为四段,每段长度为8bit。
共享内存使用key为1000,转化为16进制后为0x000003e8。
创建0.0.1.1与0.0.3.1通信的tbus通道。读写队列大小都为20480000字节,描述信息为tcmcenter and its tconnd
创建0.0.1.1与0.0.3.1通信的tbus通道。读写队列大小都为20480000字节,描述信息为tcmcenter and its tconnd
需要特别说明的是priority字段,该字段是通道优先级说明,当前没有使用,没有任何含义。默认值为8。
GCIM创建
在命令行下,可以使用以下命令完成GCIM创建:
tbusmgr--conf-file=./tbusmgr.xml –-write
或者:tbusmgr –C tbusmgr.xml –W ,完成创建后tbusmgr会输出其创建的信息,我们也可以使用tbusmgr查看我们写入的信息:
tbusmgr –k1000或者 tbusmgr –Ctbusmgr.xml
我们可以使用ipcs查看当前在共享内存中的信息,与tbusmgr打印打出的消息是完全一致的,在key为0x3e8上申请了192408字节大小作为管理区域,在共享内存上申请了40960544字节为0.0.1.1和0.0.3.1创建了一条通道,包含两个大小为20480000字节的消息队列,其中控制信息大小为544字节,shmid 为12091401。
Tbus通道查看
Tbusmgr –k1000 –-see 0.0.3.1 或者tbusmgr –C tbusmgr.xml –-see 0.0.3.1 可以查到看0.0.3.1的通道消息,可以查看该通道下消息数量,字节数等信息。--see-all参数则查看所有通道。
我们可以使用tbusmgr给通道中写入一些测试数据:
tbusmgr-k1000 –T --src=0.0.1.1 --dst=0.0.3.1 --data-len=14
在0.0.1.1至0.0.3.1的队列中,写入14字节的测试数据。
当前通道状况如下(tbusmgr -k1000 --see 0.0.3.1--dump-binary):
MsgNum:1,队列中有一个消息
Bytes:72,长度为72个字节,部分为控制信息。
H:0,头指针指向0;
T:72,尾指针指向72,
Size:队列大小
HSeq:队列中第一个消息序列号
Seq:队列总共传输了多少消息
可以使用tbusmgr –k1000 –-clean 1清理第一条通道中的消息,本例子中就是清理0.0.3.1与0.0.1.1中的所有消息
Tbus通道删除
Tbusmgr –k1000 –-delete 1 可以清理第一条tbus通道,本例子中为0.0.3.1与0.0.1.1的通道。删除后该通道将被清理,共享内存也将被释放。而原来的第二条通道(0.0.2.1=0.0.1.1)将成为第一条通道。
如果要恢复该通道,我们可以继续使用原来的配置文件进行恢复。
tbusmgr –C tbusmgr.xml –W
可以看到0.0.1.1=0.0.2.1的创建时间按没有变化,但是增加了第二条通道0.0.3.1=0.0.1.1。tbusmgr写入GCIM时,是采用全量写入的策略,如果共享内存中已经存在该通道,则对该通道进行忽略,如果共享内存中没有存在该tbus通道,则进行创建,如果共享内存中存在多余的tbus通道,则对该tbus通道进行删除。
2.trelaymgr与GRM
GRM是本地服务器上的全局路由表,保存在共享内存中,用来记录tbus通道与远端链接的对应关系。Tbusd用该对应关系完成通道消息的转发。以下是trelaymgr.xml的简单说明。
RelayMnger
AddrTemplet8.8.8.8/AddrTemplet
RelayShmKey2688/RelayShmKey
Relays
Addr0.0.3.1/Addr
MConntcp://10.1.44.61:1027/MConn
Descrelay info for 0.0.3.1/Desc
/Relays
/RelayMnger
基于原来的示例,完成GRM的配置文件。
AddrTemplet:与tbusmgr中的字段含义相同。
RelayShmKey:共享内存key
Relays:保存对应的tbus地址与远端链接的对应关系。写入共享内存后,tbusd会把0.0.3.1上的消息使用tcp协议发送到10.1.44.61的1027端口。
写入共享内存(使用参数与tbusmgr一致):
trelaymgr -C relaymgr.xml –W
Trelaymgr –C relaymgr.xml –-delete NUM,可以删除该编号的消息转发规则。
Tbus简单应用
了解tbus实际应用细节对于运维而言,不仅可以更细致把握业务的架构与部署,应用于问题排查与故障定位,也可以通过研发的角度审视tbus以及我们的业务,多角度剖析我们的工作,提升我们的专业素养。
Tbus api简介
/* 初始化tbus系统 */
int tbus_init_ex(const char* a_pszShmKey,int a_iFlag);
/* 清理tbus系统 */
void tbus_fini(void);
/* 创建tbus句柄 */
int tbus_new(int* a_piHandle);
/* 点分十进制tbus地址转TBUSADDR类型的地址 */
int tbus_addr_aton(const char* a_pszAddr, TBUSADDR*a_piAddr);
/* 为tbus句柄绑定本地TBUS地址 */
int tbus_bind(int a_iHandle, const TBUSADDRa_iAddr);
/* 释放tbus句柄 */
void tbus_delete(int* a_piHandle);
/* 收取一条消息 */
int tbus_recv(int a_iHandle, TBUSADDR*a_piSrc, TBUSADDR* a_piDst,void* a_ppvData, size_t* a_ptLen, int a_iFlag);
/* 发送消息 */
int tbus_send(int a_iHandle, TBUSADDR*a_piSrc, TBUSADDR* a_piDst, const void* a_pvData, size_t a_iLen, int a_iFlag);
/* 取得下一个消息的指针与长度信息 */
int tbus_peek_msg(int a_iHandle, TBUSADDR*a_piSrc, TBUSADDR* a_piDst,const char** a_ppvData, size_t* a_ptLen, inta_iFlag);
api使用一般逻辑
使用tbus_init_ex初始化tbus环境
使用tbus_new创建tbus句柄
使用tbus_addr_aton把字符串tbus地址转换为TBUSADDR结构体
使用tbus_bind把tbus句柄和TBUSADDR绑定
Tbus_recv/tbus_send收发消息
使用完成后,使用tbus_delete释放tbus句柄
使用tbus_fini清理tbus环境
简单示例
Tbus通道采用上面的配置,本示例通信使用0.0.1.1与0.0.2.1进行通信,为了简单说明流程,代码没做错误处理。
文件tbus_send.cpp如下,调整tbus地址转换中的地址即为tbus_recv.cpp。
#includeiostream
#include"pal/pal.h"
#include"tbus/tbus.h"
usingnamespace std;
intmain()
{
int iRet = 0, iBusRecvHandle = 0;
TBUSADDR iSrcAddr,iDstAddr;
char szBuf[1024] = "this is atsf4g tbus test! ";
tbus_init_ex("1000", 0); //初始化
tbus_new(iBusRecvHandle); //创建tbus句柄
//tbus地址转换,两个地址互换后保存即为tbus_recv.cpp
tbus_addr_aton("0.0.1.1",iSrcAddr);
tbus_addr_aton("0.0.2.1",iDstAddr);
//tbus地址绑定
tbus_bind(iBusRecvHandle, iSrcAddr);
//发送消息 this is a tsf4g tbus test!
tbus_send(iBusRecvHandle,iSrcAddr, iDstAddr, szBuf, strlen(szBuf), 0);
size_t iRecvLen = sizeof(szBuf);
//接收消息,打印消息或者打印No msg in tbus channel.
iRet = tbus_recv(iBusRecvHandle,iDstAddr, iSrcAddr, szBuf, iRecvLen, 0);
if (TBUS_ERR_CHANNEL_EMPTY ==(unsigned)iRet)
{
cout "No msg in tbuschannel." endl;
}else {
cout "Recv Data: " szBuf endl;
}
//tbus 清理
tbus_delete(iBusRecvHandle);
tbus_fini();
return 0;
}
简单编译生成tbus_send和tbus_recv可执行文件(TSF4G为tsf4g安装目录):
g++ -c-fPIC -I${TSF4G}/include/ tbus_send.cpp -o tbus_send.o
g++ -otbus_send tbus_send.o -L${TSF4G}/lib/ ${TSF4G}/lib/libtsf4g.a -Wl,-Bstatic-lscew -lexpat -Wl,-Bdynamic -lpthread
g++ -c-fPIC -I${TSF4G}/include/ tbus_recv.cpp -o tbus_recv.o
g++ -otbus_recv tbus_recv.o -L${TSF4G}/lib/ ${TSF4G}/lib/libtsf4g.a -Wl,-Bstatic-lscew -lexpat -Wl,-Bdynamic –lpthread
执行结果:
Tbus运维应用-为python扩展
Tbus提供了快速高效的进程通信接口,让上层逻辑基本可以完全忽略消息的收发与流转,为快速搭建中小型乃至大型应用提供了强有力的支持。该收益不仅仅是针对C++,针对内部常用的python更是如此。业务应用需要对外提供服务,前端还需要搭载公共组件tconnd,运维内部系统完全对内服务,逻辑服务加上tbus就能完成非持久化存储的部分构建(同理,持久化部分可以考虑使用tormsvr进行代理),极大降低了系统构建的复杂度(采用tcm-tagent管理更能降低了后续管理的成本)。
Tsf4g当前虽然没有为python提供可用的api,但是如今使用python与C++构建混合系统的技术日臻完善,我们可以为python扩展tbus接口。以下是使用第三方库boost.python为python封装tbus接口的简单探讨。
构建环境
系统:Tlinux1.2
Gcc:4.4.6(tlinux1.2默认版本)
Boost.python:1.49。lib目录~/lib/boost1.49,库文件~/include/boost/
Python:2.7.3,默认安装目录/usr/local/。
(该示例继续沿用上一个例子的tbus环境)
Tlinux1.2 上python默认版本是2.6.6,由于没有库文件,为了获取库文件,所以升级上2.7.3,python版本可以在其官网()获取到。
Boost.python是boost的一个子库,为python与C++交互提供了简单易用的接口,使用前需要编译,boost库可以在其官网()下载。完成python安装以及boost.python编译后,我们可以开始为python扩展tbus的动态库了:
针对tbus api进行简单类封装(以下的tbus.hpp文件);
使用boost.python对1步骤中的tbus类进行python封装(以下的libtbus.cpp)。
libtbus库编译,完成编译后就可以在python环境下导入tbus了。
说明:步骤1不是必须的,可以直接对tbus原始api进行python封装。这里对tbus进行简单的封装是为了简化示例。
文件Tbus.hpp
#ifndefTBUS_HPP
#defineTBUS_HPP
#include"pal/pal.h"
#include"tbus/tbus.h"
class Tbus{
protected:
std::string shm_key;
std::string send_channel;
std::string recv_channel;
int bus_handler ;
TBUSADDR send_addr;
TBUSADDR recv_addr;
public:
Tbus(std::string key, std::string send,std::string recv) : shm_key(key), send_channel(send), recv_channel(recv), bus_handler(0){}
bool init(){
if (TBUS_SUCCESS !=tbus_init_ex(shm_key.c_str(), 0)) {
std::cout "Tbus init failed!" std::endl;
return false;
}
if (TBUS_SUCCESS !=tbus_new((this-bus_handler))) {
std::cout "Tbus create bus handler failed!" std::endl;
return false;
}
if (TBUS_SUCCESS !=tbus_addr_aton(this-send_channel.c_str(), send_addr)) {
std::cout "Tbus failed to convert " this-send_channel
" to addr." std::endl;
return false;
}
if (TBUS_SUCCESS !=tbus_addr_aton(this-recv_channel.c_str(), recv_addr)) {
std::cout "Tbus failed to convert " this-recv_channel
" to addr." std::endl;
return false;
}
if (TBUS_SUCCESS !=tbus_bind(bus_handler, send_addr)){
std::cout "Tbus bind failed!" std::endl;
return false;
}
return true;
}
int send_message(const std::string message){
return tbus_send(bus_handler,send_addr, recv_addr, message.c_str(), message.length(), 0);
}
boost::python::str recv_message(){
char buffer[1024] = {0};
size_t recv_len = 1024;
int ret =tbus_recv(bus_handler, recv_addr, send_addr, buffer,
recv_len,0);
if (TBUS_SUCCESS == ret){
returnboost::python::str(buffer, recv_len);
}
returnboost::python::str("None");
}
void finit(){
tbus_delete(bus_handler);
tbus_fini();
}
~Tbus(){
this-finit();
}
};
#endif
代码说明:
Tbus:构造函数,参数为共享内存key,收发端进程的tbus地址;
Init:初始化函数,初始化tbus环境,完成tbus句柄以及tbus地址内部转换;
send_message:消息发送函数,为了快速完成封装,只能发送string
recv_message:消息接收函数,考虑到python的使用,直接返回python下的str类型数据;
finit:tbus环境清理,删除tbus句柄,退出tbus。
文件libtbus.cpp
#include"boost/python.hpp"
#include"tbus.hpp"
BOOST_PYTHON_MODULE(libtbus){
namespace bpy = boost::python;
bpy::class_Tbus("Tbus", bpy::initstd::string,std::string, std::string())
.def("init",Tbus::init)
.def("send_message", Tbus::send_message)
.def("recv_message", Tbus::recv_message)
.def("finit",Tbus::finit);
bpy::def("tbus_error_string",tbus_error_string);
}
代码说明:
使用boost.python封装tbus.hpp为libtbus库。封装Tbus类的五个函数:构造函数,init,send_message,recv_message以及finit。具体boost.python语法含义可以参考官方文档(完整的说明那就是另外一篇帖子了)
简单Makefile
(请注意库文件目录,替换为自己实际目录)
CXXFLAGS=-I/data/home/jimwu/include/tsf4g/-I/usr/local/include/python2.7 -I/data/home/jimwu/include/
LDFLAGS=-L/data/home/jimwu/lib/boost1.49-L/usr/local/lib/python2.7 -L/data/home/jimwu/lib/tsf4g/
libtbus.so: libtbus.o /usr/local/lib/libpython2.7.a
在并行计算中,不同计算机之间需要数据通信,我想实现的是:多台计算机共享服务器内存中的数据
从原理上来说,你现有的环境为多计算机(multi-computer),而你想要的是共享内存式的共享模式,这是很难做到的。共享内存模式一般对应于多处理器(multi-processor)的结构,其与多计算机是MIMD的两个实例。多计算机一般使用消息传递共享模式,经典的是MPI。你的需求其实很早就有人提出来了,类似于DSM模型,即distributed shared memory,不过那个绝不是靠普通PC机搭出来的,也绝不是走网线的,一定是大厂商定制开发的,所以这个你就别想了。另一种解决方案是靠高层抽象,将消息传递抽象成共享存储,但效率比较低,不过貌似大规模分布式系统已采用这种方案,对小型系统没啥优势的。
综上所述,用于并行计算的多计算机使用共享内存模式很难办到。
web服务器之间如何做到内存共享
这个是分布式计算的知识,通过总线共享内存,或者通过消息机制互访内存,在内存共享的时候要注意Cache的一致性。我懂的就这些吧。
共享内存实现原理
哪有什么共享内存?好像什么云盘,云储存,其实都是把东西放到了很远的服务器里,存着,服务器懂吧?几万台用铁盒子装着的电脑,电脑的内存特别大,一台电脑的内存相当于几千台你的手机那么大。
SUCCESS !=tbus_bind(bus_handler, send_addr)){std::cout "Tbus bind failed!" std::endl;return false;}return tru
义相同。RelayShmKey:共享内存keyRelays:保存对应的tbus地址与远端链接的对应关系。写入共享内存后,tbusd会把0.0.3.1上的消息使用tcp协议发送到10.1.44.61的1027端口。写入共享内存(使用参数与tbusmg
BUS_HPP#include"pal/pal.h"#include"tbus/tbus.h"class Tbus{protected:std::string shm_key;std::string send_channe
f[1024] = "this is atsf4g tbus test! ";tbus_init_ex("1000", 0); //初始化tbus_new(iBusRecvHandle); //创建tbus句柄/