向 Vertica 通知资源要求

在隔离模式下运行 UDx 时,Vertica 会监控其内存和文件句柄的使用情况。如果 UDx 使用超过数 MB 内存或使用任意文件句柄,则它应向 Vertica 说明其资源要求。获知 UDx 的资源要求后,Vertica 能够确定是可以立即运行该 UDx,还是需要将请求排入队列直至足够的资源变为可用于运行该 UDx。

在某些情况下,可能难以确定 UDx 查询所需的内存数量。例如,如果 UDx 从数据集提取唯一的数据元素,数据项的数量可能不会受到限制。在这种情况下,您可以在测试环境中运行 UDx 并在节点上监控该 UDx 在处理多个不同大小的查询时的内存使用量,然后基于该 UDx 在生产环境中可能面临的最坏情况推断其内存使用量,这种技术很有用。在所有情况下,通常最好为您向 Vertica 告知的 Udx 内存使用量添加安全余地。

UDx 可通过在其工厂类中实施 getPerInstanceResources() 函数来向 Vertica 通知其资源需求(请参阅 SDK 文档中的 Vertica::UDXFactory::getPerInstanceResources())。如果 UDx 的工厂类实施此函数,Vertica 将调用此函数以确定 UDx 所需的资源。

getPerInstanceResources() 函数将收到 Vertica::VResources 结构的一个实例。此结构包含用于设置 UDx 所需的内存数量和文件句柄数的字段。默认情况下,Vertica 服务器会为 UDx 的每个实例分配零字节内存和 100 个文件句柄。

getPerInstanceResources() 函数的实施基于 UDx 可能使用的最大资源数量为 UDx 函数的每个实例设置 VResources 结构中的字段。因此,如果 UDx 的 processBlock() 函数所创建的数据结构最多使用 100 MB 内存,则 UDx 必须将 VResources.scratchMemory 字段设置为 104857600(100 MB 等于的字节数)或以上。通过将该数字增加至 UDx 在正常情况下应使用的内存数量以上,为您自己保留一个安全边际。在此示例中,合适做法是分配 115000000 字节(刚好低于 110 MB)。

以下 ScalarFunctionFactory 类演示了调用 getPerInstanceResources() 以向 Vertica 通知为 UDx 分配资源中所示的 MemoryAllocationExample 类的内存要求。该类会向 Vertica 说明 UDSF 需要 510 MB 内存(为保持安全大小,此容量比 UDSF 实际分配的容量稍多)。

class MemoryAllocationExampleFactory : public ScalarFunctionFactory
{
    virtual Vertica::ScalarFunction *createScalarFunction(Vertica::ServerInterface
                                                            &srvInterface)
    {
        return vt_createFuncObj(srvInterface.allocator, MemoryAllocationExample);
    }
    virtual void getPrototype(Vertica::ServerInterface &srvInterface,
                              Vertica::ColumnTypes &argTypes,
                              Vertica::ColumnTypes &returnType)
    {
        argTypes.addInt();
        argTypes.addInt();
        returnType.addInt();
    }
    // Tells Vertica the amount of resources that this UDF uses.
    virtual void getPerInstanceResources(ServerInterface &srvInterface,
                                          VResources &res)
    {
        res.scratchMemory += 1024LL * 1024 * 510; // request 510MB of memory
    }
};