【问题标题】:VMWare ESXi in memory database shared across VMs on a single blade内存数据库中的 VMWare ESXi 在单个刀片上的虚拟机之间共享
【发布时间】:2017-02-13 22:18:22
【问题描述】:

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

【问题讨论】:

    标签: vmware shared-memory virtualization esxi


    【解决方案1】:

    VMCI 是您所需要的。不幸的是,VMCI 在 vSphere 6 及更高版本的 VM 之间已被弃用。

    【讨论】:

      【解决方案2】:

      根据 vSockets API 文档,它说:

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

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

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

      有一个 SDK,您可以尝试使用它来创建程序,但它不适合胆小的人,有些人已经花了几天时间试图让它编译,所以如果您愿意,您可以尝试这条路线,但我不推荐它。谷歌搜索“VMWare ESXi 工具链”。

      但是,如果您正在寻找更快的途径让自己的服务器在 ESXi 上运行,并且准备使用 Python,您会发现 5.5 和 6.0 都带有相当最新的 Python(Python 2.7. 9 在 ESXi v6.0 上)。 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))
      

      在 ESXi 上使用 Python 的一个警告是,您可以使用的内存似乎有限:我尝试分配一个 16MB 的缓冲区,但 Python 拒绝给我它并出现内存错误,但这不是问题我当时在做什么,所以我没有费心去想办法解决它。我怀疑有一个设置可以解决这个问题。

      在 ESXi 引导时启动脚本留给读者作为练习,但这应该可以帮助您入门。玩得开心!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-31
        • 2017-11-27
        • 2018-11-29
        • 2019-07-04
        相关资源
        最近更新 更多