存储系统python api扩展模块开发
来源:互联网 发布:剑三毛毛捏脸数据 编辑:程序博客网 时间:2024/05/18 12:31
背景
如千万级并发的分布式kv缓存系统构建及运营实践中所述,在我们重建了我们推荐业务的底层分布式缓存系统后,我们需要迁移我们的业务,业务方需要通过c++/java/python接口接入我们的系统,其中,python的api接入方式我们采用的是开发python扩展模块的方式实现的,在线上生产环境稳定运营近2年时间,无一次线上问题。
实现说明
- 添加python头文件(一般是在/usr/local/include/python2.x):
#include <Python.h>
- 定义模块包装方法数组,创建好包装函数后,需要在该数组中把它们列出来,以便python解释器导入并调用它们,如我们的模块中定义了如下数组:
static PyMethodDef pythonVdeClientApiMethods[] ={ {"init_vde", wrap_init_vde, METH_VARARGS, "init vde"}, {"sync_put", wrap_sync_put, METH_VARARGS, "sync put"}, {"sync_get", wrap_sync_get, METH_VARARGS, "sync get"}, {"sync_remove", wrap_sync_remove, METH_VARARGS, "sync remove"}, {"set_timeout", wrap_set_timeout, METH_VARARGS, "set timeout"}, {"close_vde", wrap_close_vde, METH_VARARGS, "close vde"}, {NULL, NULL}};
说明:
init_vde、sync_put、sync_get、sync_remove、set_timeout、close_vde是提供给业务层使用的python api,实际是调用对应的包装函数的实现。
- 增加模块初始化函数void initpython_vde_client_api()。
Python解释器规定所有的初始化函数的函数名都必须以init开头,并加上模块的名字,这样导入模块的时候,python解释器才能识别并调用模块初始化函数。对于我们的模块python_vde_client_api而言,相应的初始化函数为:
extern "C" void initpython_vde_client_api(){ PyObject* m; m = Py_InitModule("python_vde_client_api", pythonVdeClientApiMethods);}
- 为包装的函数添加函数实现
static PyObject* wrap_init_tair(PyObject* self, PyObject* args){ if (g_python_client_api != NULL) { return Py_BuildValue("i", 1); } ... if (! PyArg_ParseTuple(args, "sssisi", &cs_addr, &slave_addr, &group_name, &timeout_ms, &log_file_path, &i_log_level)) { return Py_BuildValue("i", -2); } ... if (g_python_client_api != NULL) { return Py_BuildValue("i", 1); } g_python_client_api = new python_tair_client_api(); bool bRet = g_python_client_api->init_tair(cs_addr, slave_addr, group_name, 0, timeout_ms, log_file_path, s_log_level.c_str()); if (!bRet) { ... return Py_BuildValue("i", -1); } ... return Py_BuildValue("i", 0);}static PyObject* wrap_sync_put(PyObject* self, PyObject* args){ ...}static PyObject* wrap_sync_get(PyObject* self, PyObject* args){...}static PyObject* wrap_sync_remove(PyObject* self, PyObject* args){...}static PyObject* wrap_set_timeout(PyObject* self, PyObject* args){...}static PyObject* wrap_close_tair(PyObject* self, PyObject* args){...}
- python扩展模块数据类型
Py_BuildValue用法参考:
以我们的模块中put、get操作为例:
static PyObject* wrap_sync_put(PyObject* self, PyObject* args){ if (! PyArg_ParseTuple(args, "ss#iii", &key, &value, &len, &len, &area, &expired)) { return Py_BuildValue("i", -2); } int32_t ret = g_python_client_api->sync_put(key, value, len, area, expired, 0); return Py_BuildValue("i", ret);}static PyObject* wrap_sync_get(PyObject* self, PyObject* args){ if (! PyArg_ParseTuple(args, "si", &key, &area)) { return Py_BuildValue("{s:i}", "result", -2); } ... PyObject* obj = Py_BuildValue("{s:i,s:s#,s:i,s:l}", "result", ret, "data", data->get_data(), data->get_size(), "data_size", data->get_size(), "edate", expiretime); ... return obj;}
- Makefile
python扩展模块的编译与其他常规so的编译差异不大,附上我们模块编译的makefile,仅供参考。
SOURCE_PATH=$(shell pwd)VDE_DIR=$(shell pwd)/../../DEF_INCLUDE = -I${VDE_DIR}/src/client -I/usr/include/python2.6 -I/usr/lib/python2.6/configDEF_FLAGS =DEF_LIBS = ${VDE_DIR}/src/client/libvdeclientapi.aDEF_LIB_DIRS = include $(VDE_DIR)/makefile.inclTARGET = python_vde_client_api.soall : $(TARGET)vdeclient_python_SOURCES = $(wildcard $(SOURCE_PATH)/*.cpp)vdeclient_python_OBJS = $(patsubst %.cpp, %.o, $(vdeclient_python_SOURCES))$(TARGET) : $(vdeclient_python_OBJS) $(CXX) $(INCLUDE) -fPIC -shared $^ -o $@ $(LDFLAGS)clean: $(RM) $(TARGET) $(vdeclient_python_OBJS)
- 其他
我们扩展模块的第一版本实现中,内部定义了一个全局的存储系统api对象,模块导入时初始化,无法多次初始化得到多个对象,因此,业务方调用python api时无法连接多个集群,只能启动多个进程连接不同的集群做相关的业务处理,这个问题我们已在我们的第二版本中优化,支持多次创建不同的python对象,以连接多个不同的集群。
阅读全文
0 0
- 存储系统python api扩展模块开发
- python扩展模块开发
- Gmond扩展Python度量模块开发
- <转>Ganglia的Python扩展模块开发
- 《扩展和嵌入python解释器》1.12 为扩展模块提供C API
- Python一些扩展模块
- ctypes模块扩展python
- Python扩展模块
- 开发PHP扩展模块
- 开发PHP扩展模块
- 开发PHP扩展模块
- Python sqlite3 模块 API
- Python sqlite3 模块 API
- Python Image模块API
- Python扩展模块的细节(
- python 解释器, 扩展模块
- python调用c++扩展模块
- python的soap模块扩展
- ssh项目心得之传值
- 全文检索技术Lucene入门和学习、与数据库数据结合的demo实现
- NPOI导出WPF DataGrid控件显示数据
- jsp周末总结
- 三维坐标系中旋转矩阵R的作用和演示
- 存储系统python api扩展模块开发
- 【OpenCV】基于OpenCV的双目视觉测试
- Java 并发编程(八)Future和Callable,CompletionService的使用
- 论文代发费用
- 作业.输出全部希腊字母
- angularjs获取json解析(http)
- 多图上传
- CS231n课程Python Numpy教程三:SciPy
- Dialog 控件的使用