在单个刀片上跨虚拟机共享的内存数据库中的VMWare ESXi



可能是一个愚蠢的问题(对不起!),但是在VMWare ESXi中,是否有任何方法可以在同一刀片上的vm之间共享内存,这样两个vm可以通过共享内存块执行进程间通信,而不是使用消息传递?我知道我可以跨vm共享内存,但我感兴趣的是进程间通信。这样做的目的是使两个VM能够快速访问内存中的数据库,但是(与托管操作系统解决方案不同)如果一个VM出现故障,另一个VM仍然可以愉快地继续工作。

根据vSockets API文档,它说:

"最初的VMCI库是作为工作站6.0的实验性C语言接口发布的。VMCI包括一个数据报API和一个共享内存API。这两个接口都在Workstation 6.5中停止使用。"

所以现在看来你只能使用vmci SOCK_DGRAM或SOCK_STREAM套接字。它们的行为很像tcp/ip套接字,网上有很多关于如何编写使用它们的代码的信息,基本上只需要标头vmci_sockets.h就可以了。

你会发现vsocket通信的客户端很简单,但是你需要写一些服务器在ESXi主机上运行来承载你的DB,这是一个棘手的部分。如果您在ESXi上启用了ssh并进行了嗅探,您将发现一个带有/dev/vsock设备的非常类似unix的系统,您可以查询该设备以获得vsocket协议族(对于您的客户机可能不同,您需要调用ioctl)。不幸的是(我尝试过),简单地编译64位静态链接的Linux二进制文件只会给你带来段错误,因为ESXi操作系统与Linux不够相似。

有一个SDK,你可以尝试用它来创建程序,但是它不适合胆小的人,有些人花了几天的时间只是试图让它编译,所以你可以尝试这条路,如果你想,但我不推荐它。谷歌"VMWare ESXi工具链"。

然而,如果你正在寻找一种更快的方法来让你自己的服务器在ESXi上运行,并且准备使用Python,你会发现5.5和6.0都带有相当最新的Python (ESXi v6.0上的Python 2.7.9)。VMWare没有帮助地删除了。py库文件,只留下。pyc文件,所以你不能很容易地看到这是否与标准版本不同,但它的功能肯定足以让一个基本的套接字服务器运行。

Python套接字模块不理解vmci套接字系列,因此您需要使用ctypes来绕过它直接调用c库套接字函数。您可以使用纯python创建套接字,甚至调用listen(),但例如bind()隐式地期望您处理sockaddr_in结构。

所以你需要检查vmci_sockets.h头,并提出Python ctypes结构和函数来镜像你在C中使用的结构和函数,例如:

class sockaddr_vm(Structure):
    _fields_ = [("svm_family", c_ushort),
                ("svm_reserved1", c_ushort),
                ("svm_port", c_uint),
                ("svm_cid", c_uint),
                ("svm_zero", c_uint),
               ]

这可以被传递到libc bind/recvfrom/sendto调用中,你可以使用:

libc = cdll.LoadLibrary("libc.so.6")

然后你可以绕过python的套接字模块绑定到你的套接字,即

addr = sockaddr_vm()
addr.svm_family = af     # address family obtained from ioctl
addr.svm_reserved1 = 0
addr.svm_cid = VMADDR_CID_ANY    # 0xffffffff
addr.svm_port = port
addr.svm_zero = 0
# s is the socket, created with python socket.socket()
out = libc.bind(s.fileno(), pointer(addr), sizeof(addr))

Python在ESXi上的一个警告是,你似乎在内存中受到限制,你可以玩:我尝试分配一个16MB的缓冲区,Python拒绝给我内存错误,但这不是我当时正在做的事情的问题,所以我没有费心试图找到一种方法。我想有一个设置可以解决这个问题。

在ESXi启动时启动脚本留给读者作为练习,但这应该让您开始。玩得开心!

VMCI是您所需要的。不幸的是,VMCI在vSphere 6及以上版本的虚拟机中已被弃用。

最新更新