注意
本文档适用于 Ceph 开发版本。
Librados (Python)
The rados
该模块是一个用于的薄Python包装器librados
.
安装
要安装Ceph的Python库,请参阅获取 Python 的 librados.
入门指南
您可以使用Python创建自己的Ceph客户端。以下教程将向您展示如何导入Ceph Python模块,连接到Ceph集群,并作为用户执行对象操作。client.admin
用户。
Note
要使用Ceph Python绑定,您必须能够访问正在运行的Ceph集群。要快速设置一个,请参阅入门指南.
首先,为您的Ceph客户端创建一个Python源文件。
vim client.py
导入模块
要使用rados
导入模块,将其导入您的源文件。
1 import rados
配置集群句柄
在连接到Ceph存储集群之前,创建一个集群句柄。默认情况下,集群句柄假设一个名为ceph
(即部署工具的默认值,以及我们的入门指南),以及client.admin
用户名。您可以将这些默认值更改为满足您的需求。
要连接到Ceph存储集群,您的应用程序需要知道在哪里找到Ceph监视器。通过指定Ceph配置文件的路径来向您的应用程序提供此信息,该配置文件包含初始Ceph监视器的位置。
1 import rados, sys
2
3 #Create Handle Examples.
4 cluster = rados.Rados(conffile='ceph.conf')
5 cluster = rados.Rados(conffile=sys.argv[1])
6 cluster = rados.Rados(conffile = 'ceph.conf', conf = dict (keyring = '/path/to/keyring'))
Ensure that the conffile
参数提供您的Ceph配置文件的路径和文件名。您可以使用sys
模块来避免硬编码Ceph配置路径和文件名。
您的Python客户端还需要一个客户端密钥环。在此示例中,我们使用默认的client.admin
密钥。如果您希望在创建集群句柄时指定密钥环,您可以使用conf
参数。或者,您可以在Ceph配置文件中指定密钥环路径。例如,您可以在Ceph配置文件中添加如下行:
keyring = /path/to/ceph.client.admin.keyring
要了解有关通过Python修改配置的更多详细信息,请参阅配置.
连接到集群
一旦您配置了集群句柄,就可以连接到集群。通过集群连接,您可以执行返回集群信息的方法。
1 import rados, sys
2
3 cluster = rados.Rados(conffile='ceph.conf')
4 print("\nlibrados version: {}".format(str(cluster.version())))
5 print("Will attempt to connect to: {}".format(str(cluster.conf_get('mon host'))))
6
7 cluster.connect()
8 print("\nCluster ID: {}".format(cluster.get_fsid()))
9
10 print("\n\nCluster Statistics")
11 print("==================")
12 cluster_stats = cluster.get_cluster_stats()
13
14 for key, value in cluster_stats.items():
15 print(key, value)
默认情况下,Ceph身份验证是on
。您的应用程序需要知道密钥环的位置。的python-ceph
模块没有默认位置,因此您需要指定密钥环路径。指定密钥环的最简单方法是将它添加到Ceph配置文件。以下Ceph配置文件示例使用了client.admin
密钥环。
1 [global]
2 # ... elided configuration
3 keyring = /path/to/keyring/ceph.client.admin.keyring
管理池
连接到集群时,的Rados
API允许您管理池。您可以列出池,检查池是否存在,创建池并删除池。
1 print("\n\nPool Operations")
2 print("===============")
3
4 print("\nAvailable Pools")
5 print("----------------")
6 pools = cluster.list_pools()
7
8 for pool in pools:
9 print(pool)
10
11 print("\nCreate 'test' Pool")
12 print("------------------")
13 cluster.create_pool('test')
14
15 print("\nPool named 'test' exists: {}".format(str(cluster.pool_exists('test'))))
16 print("\nVerify 'test' Pool Exists")
17 print("-------------------------")
18 pools = cluster.list_pools()
19
20 for pool in pools:
21 print(pool)
22
23 print("\nDelete 'test' Pool")
24 print("------------------")
25 cluster.delete_pool('test')
26 print("\nPool named 'test' exists: {}".format(str(cluster.pool_exists('test'))))
输入/输出上下文
从Ceph存储集群读取和写入需要输入/输出上下文(ioctx)。您可以使用open_ioctx()
或open_ioctx2()
类的Rados
方法创建ioctx。的ioctx_name
参数是池的名称,是您希望使用的池的ID。pool_id
is the ID of the pool you wish to use.
1 ioctx = cluster.open_ioctx('data')
或
1 ioctx = cluster.open_ioctx2(pool_id)
一旦您有了I/O上下文,就可以读取/写入对象,扩展属性,并执行其他一些操作。完成操作后,请确保关闭连接。例如:
1 print("\nClosing the connection.")
2 ioctx.close()
写入、读取和删除对象
一旦您创建了I/O上下文,就可以将对象写入集群。如果您写入一个不存在的对象,Ceph会创建它。如果您写入一个存在的对象,Ceph会覆盖它(除非您指定了一个范围,然后它只覆盖该范围)。您可以读取对象(和对象范围)从集群。您还可以从集群中删除对象。例如:
1print("\nWriting object 'hw' with contents 'Hello World!' to pool 'data'.")
2ioctx.write_full("hw", "Hello World!")
3
4print("\n\nContents of object 'hw'\n------------------------\n")
5print(ioctx.read("hw"))
6
7print("\nRemoving object 'hw'")
8ioctx.remove_object("hw")
写入和读取XATTRS
一旦您创建了一个对象,就可以将扩展属性(XATTRS)写入对象,并从对象中读取XATTRS。例如:
1print("\n\nWriting XATTR 'lang' with value 'en_US' to object 'hw'")
2ioctx.set_xattr("hw", "lang", "en_US")
3
4print("\n\nGetting XATTR 'lang' from object 'hw'\n")
5print(ioctx.get_xattr("hw", "lang"))
列出对象
如果您想查看池中对象的列表,您可以检索对象列表并使用对象迭代器迭代它们。例如:
1object_iterator = ioctx.list_objects()
2
3while True :
4
5 try :
6 rados_object = object_iterator.__next__()
7 print("Object contents = {}".format(rados_object.read()))
8
9 except StopIteration :
10 break
11
12# Or alternatively
13[print("Object contents = {}".format(obj.read())) for obj in ioctx.list_objects()]
The Object
类提供了一个文件接口到对象,允许您读取和写入内容和扩展属性。使用I/O上下文的对象操作提供额外的功能和异步功能。
集群句柄 API
The Rados
类提供了对Ceph存储守护程序的接口。
配置
The Rados
类提供了获取和设置配置值、读取Ceph配置文件和解析参数的方法。您不需要连接到Ceph存储集群即可调用以下方法。有关设置的详细信息,请参阅存储集群配置。
- Rados。conf_get(选项)
Rados.conf_get(self, str option: str) -> Optional[str]
- 参数:
选项 (
str
) -- 要读取的选项- 返回类型:
Optional
[str
]- 返回:
选项的值或None
- Raises:
TypeError
- Rados。conf_set(选项, val)
Rados.conf_set(self, str option: str, str val: str)
- 参数:
选项 (
str
) -- 要设置的选项选项-- 选项的值
- Raises:
TypeError
,ObjectNotFound
- Rados。conf_read_file(path=无)
Rados.conf_read_file(self, str path: Optional[str] = None)
- 参数:
path (
Optional
[str
]) -- 配置文件的路径
- Rados。conf_parse_argv(args)
Rados.conf_parse_argv(self, args: Sequence[str])
- Rados。version()
Rados.version(self) -> Version
librados
a元组- 返回类型:
Version
- 返回:
libcephfs 版本的组件
(major, minor, extra)
组分的
连接管理
一旦您配置了集群句柄,就可以连接到集群,检查集群fsid
,检索集群统计信息,并从集群断开连接(关闭)。您还可以断言集群句柄处于特定状态(例如,“配置”,“连接”等)。
- Rados。connect(timeout=0)
Rados.connect(self, int timeout: int = 0)
- 参数:
timeout (
int
) -- 任何提供的超时值目前被忽略。
- Rados。shutdown()
Rados.shutdown(self)
- Rados。get_fsid()
Rados.get_fsid(self) -> str
- Raises:
Error
- 返回类型:
str
- 返回:
集群fsid
- Rados。get_cluster_stats()
Rados.get_cluster_stats(self) -> Dict[str, int]
这告诉您总空间、已用空间、可用空间和对象数量。当写入数据时,这些信息不会立即更新,它们最终是一致的。
Dict
[str
,int
]kb
(int) - 总空间kb_used
(int) - 已用空间kb_avail
(int) - 可用空间num_objects
(int) - 对象数量
Pool Operations
要使用池操作方法,您必须首先连接到Ceph存储集群。您可以列出可用池,创建池,检查池是否存在,并删除池。
- Rados。list_pools()
Rados.list_pools(self) -> List[str]
- 返回类型:
List
[str
]- 返回:
池名称列表。
- Rados。create_pool(pool_name, crush_rule=无, auid=无)
Rados.create_pool(self, str pool_name: str, int crush_rule: Optional[int] = None, int auid: Optional[int] = None)
- 参数:
pool_name (
str
) -- 要创建的池的名称crush_rule (
Optional
[int
]) -- 新池中用于放置的规则auid (
Optional
[int
]) -- 新池所有者的ID
- Raises:
TypeError
,Error
- Rados。pool_exists(pool_name)
Rados.pool_exists(self, str pool_name: str) -> bool
- 参数:
pool_name (
str
) -- 要检查的池的名称- Raises:
TypeError
,Error
- 返回类型:
bool
- 返回:
如果池存在,则为true;否则为false。
- Rados。delete_pool(pool_name)
Rados.delete_pool(self, str pool_name: str)
池会立即从集群中移除,但实际数据的删除是在后台进行的。
- 参数:
pool_name (
str
) -- 要删除的池的名称- Raises:
TypeError
,Error
CLI命令
Ceph CLI命令内部使用以下librados Python绑定方法。
为了发送命令,请选择正确的方法并选择正确的目标。
- Rados。mon_command(cmd, inbuf, timeout=0, target=无)
向mon发送命令。
mon_command[_target](cmd, inbuf, outbuf, outbuflen, outs, outslen)
- 参数:
cmd (
str
) -- JSON格式化的字符串。inbuf (
bytes
) -- 可选字符串。timeout (
int
) -- 此参数被忽略。target (
Union
[int
,str
,None
]) -- 特定mon的名称或等级。可选
- 返回类型:
Tuple
[int
,bytes
,str
]- 返回:
(int ret, string outbuf, string outs)
Example:
>>> import json >>> c = Rados(conffile='/etc/ceph/ceph.conf') >>> c.connect() >>> cmd = json.dumps({"prefix": "osd safe-to-destroy", "ids": ["2"], "format": "json"}) >>> c.mon_command(cmd, b'')
- Rados。osd_command(osdid, cmd, inbuf, timeout=0)
- Rados。osd_command(osdid, cmd, inbuf, outbuf, outbuflen, outs, outslen) 无
- 返回类型:
Tuple
[int
,bytes
,str
]- 返回:
(int ret, string outbuf, string outs)
- Rados。mgr_command(cmd, inbuf, timeout=0, target=无)
- 返回类型:
Tuple
[int
,str
,bytes
]- 返回:
(int ret, string outbuf, string outs)
- Rados。pg_command(pgid, cmd, inbuf, timeout=0)
- Rados。pg_command(pgid, cmd, inbuf, outbuf, outbuflen, outs, outslen) 无
- 返回类型:
Tuple
[int
,bytes
,str
]- 返回:
(int ret, string outbuf, string outs)
输入/输出上下文 API
要向Ceph对象存储写入数据并从中读取数据,您必须创建一个输入/输出上下文(ioctx)。的Rados类提供open_ioctx()和open_ioctx2()方法。其余ioctx
操作涉及调用Ioctx和其他类的
- Rados。open_ioctx(ioctx_name)
Rados.open_ioctx(self, str ioctx_name: str) -> Ioctx
io上下文允许您在特定池内执行操作。
- 参数:
ioctx_name (
str
) -- 池的名称- Raises:
TypeError
,Error
- 返回类型:
Ioctx
- 返回:
Rados Ioctx对象
- Ioctx。require_ioctx_open()
Ioctx.require_ioctx_open(self)
- Raises:
IoctxStateError
- Ioctx。get_stats()
Ioctx.get_stats(self) -> Dict[str, int]
- 返回类型:
Dict
[str
,int
]- 返回:
字典包含以下键:
num_bytes
(int) - 池的大小(以字节为单位)num_kb
(int) - 池的大小(以千字节为单位)num_objects
(int) - 池中的对象数量num_object_clones
(int) - 对象克隆数量num_object_copies
(int) - 对象副本数量num_objects_missing_on_primary
(int) - 对象数量主要缺失的对象
num_objects_unfound
(int) - 未找到的对象数量num_objects_degraded
(int) - 降级对象数量num_rd
(int) - 读取的字节数num_rd_kb
(int) - 读取的千字节数num_wr
(int) - 写入的字节数num_wr_kb
(int) - 写入的千字节数
- Ioctx。get_last_version()
Ioctx.get_last_version(self) -> int
这暴露了通过此io上下文读取或写入的最后对象的内部版本号
- 返回类型:
int
- 返回:
最后使用的对象版本
- Ioctx。close()
Ioctx.close(self)
这只是告诉librados您不再需要使用io上下文。如果它上面有挂起的异步请求,它可能不会立即释放,但在调用此函数后,您不应该再使用该io上下文。
对象操作
Ceph存储集群将数据存储为对象。您可以同步或异步地读取和写入对象。您可以从偏移量读取和写入。对象有一个名称(或键)和数据。
- Ioctx。aio_write(object_name, to_write, offset=0, oncomplete=无, onsafe=无)
Ioctx.aio_write(self, str object_name: str, bytes to_write: bytes, int offset: int = 0, oncomplete: Optional[Callable[[Completion], None]] = None, onsafe: Optional[Callable[[Completion], None]] = None) -> Completion
队列写入并返回。
- 参数:
object_name (
str
) -- 对象的名称to_write (
bytes
) -- 要写入的数据offset (
int
) -- 对象中开始写入的字节偏移量oncomplete (
Optional
[Callable
[[Completion
],None
]]) -- 写入在内存中所有副本都安全且完成时要做的事情onsafe (
Optional
[Callable
[[Completion
],None
]]) -- 写入在所有副本的存储中安全且完成时要做的事情
- Raises:
Error
- 返回类型:
Completion
- 返回:
完成对象
- Ioctx。aio_write_full(object_name, to_write, oncomplete=无, onsafe=无)
Ioctx.aio_write_full(self, str object_name: str, bytes to_write: bytes, oncomplete: Optional[Callable] = None, onsafe: Optional[Callable] = None) -> Completion
对象被提供的数据填充。如果对象存在,它会被原子性地截断然后写入。
- 参数:
object_name (
str
) -- 对象的名称to_write (
bytes
) -- 要写入的数据oncomplete (
Optional
[Callable
]) -- 写入在内存中所有副本都安全且完成时要做的事情onsafe (
Optional
[Callable
]) -- 写入在所有副本的存储中安全且完成时要做的事情
- Raises:
Error
- 返回类型:
Completion
- 返回:
完成对象
- Ioctx。aio_append(object_name, to_append, oncomplete=无, onsafe=无)
Ioctx.aio_append(self, str object_name: str, bytes to_append: bytes, oncomplete: Optional[Callable] = None, onsafe: Optional[Callable] = None) -> Completion
队列写入并返回。
- 参数:
object_name (
str
) -- 对象的名称to_append (
bytes
) -- 要附加的数据offset-- 对象中开始写入的字节偏移量
oncomplete (
Optional
[Callable
]) -- 写入在内存中所有副本都安全且完成时要做的事情onsafe (
Optional
[Callable
]) -- 写入在所有副本的存储中安全且完成时要做的事情
- Raises:
Error
- 返回类型:
Completion
- 返回:
完成对象
- Ioctx。write(key, 数据, offset=0)
Ioctx.write(self, str key: str, bytes data: bytes, int offset: int = 0)
- 参数:
key (
str
) -- 对象的名称数据 (
bytes
) -- 要写入的数据offset (
int
) -- 对象中开始写入的字节偏移量
- Raises:
TypeError
- Raises:
LogicError
- 返回:
成功时为0
- Ioctx。write_full(key, 数据)
Ioctx.write_full(self, str key: str, bytes data: bytes)
对象被提供的数据填充。如果对象存在,它会被原子性地截断然后写入。
- 参数:
key (
str
) -- 对象的名称数据 (
bytes
) -- 要写入的数据
- Raises:
TypeError
- Raises:
Error
- 返回:
成功时为0
- Ioctx。aio_flush()
Ioctx.aio_flush(self)
- Raises:
Error
- Ioctx。set_locator_key(loc_key)
Ioctx.set_locator_key(self, str loc_key: str)
该键用于代替对象名称来确定对象被放入哪些放置组。这影响io上下文的所有后续操作 - 直到设置不同的定位键,此io上下文中的所有对象都将被放入同一个pg。
- 参数:
loc_key (
str
) -- 要用作对象定位器的键,或NULL以放弃任何先前设置的键- Raises:
TypeError
- Ioctx。aio_read(object_name, length, offset, oncomplete=无)
Ioctx.aio_read(self, str object_name: str, int length: int, int offset: int, oncomplete: Optional[Callable] = None) -> Completion
oncomplete将被调用,并返回读取的值以及完成:
oncomplete(completion, data_read)
- 参数:
object_name (
str
) -- 要从中读取数据的对象名称length (
int
) -- 要读取的字节数offset (
int
) -- 对象中开始读取的字节偏移量oncomplete (
Optional
[Callable
]) -- 读取完成后要执行的操作
- Raises:
Error
- 返回类型:
Completion
- 返回:
完成对象
- Ioctx。读取(key, length=8192, offset=0)
Ioctx.read(self, str key: str, int length: int = 8192, int offset: int = 0) -> bytes
- 参数:
key (
str
) -- 对象的名称length (
int
) -- 要读取的字节数(默认=8192)offset (
int
) -- 对象中开始读取的字节偏移量
- Raises:
TypeError
- Raises:
Error
- 返回类型:
bytes
- 返回:
从对象中读取的数据
- Ioctx。stat(key)
Ioctx.stat(self, str key: str) -> Tuple[int, time.struct_time]
- 参数:
key (
str
) -- 要获取统计信息的对象名称- Raises:
TypeError
- Raises:
Error
- 返回类型:
Tuple
[int
,struct_time
]- 返回:
(size,timestamp)
- Ioctx。trunc(key, size定位特定驱动器容量:)
Ioctx.trunc(self, str key: str, int size: int) -> int
如果这扩大了对象,新区域在逻辑上用零填充。如果这缩小了对象,则删除多余的数据。
- 参数:
key (
str
) -- 要调整大小的对象名称size定位特定驱动器容量: (
int
) -- 对象的新大小(以字节为单位)
- Raises:
TypeError
- Raises:
Error
- 返回类型:
int
- 返回:
成功时为0,否则引发错误
- Ioctx。remove_object(key)
Ioctx.remove_object(self, str key: str) -> bool
这不会删除对象的任何快照。
- 参数:
key (
str
) -- 要删除的对象名称- Raises:
TypeError
- Raises:
Error
- 返回类型:
bool
- 返回:
成功时为True
对象扩展属性
您可以在对象上设置扩展属性(XATTRS)。您可以检索对象或XATTRS的列表并迭代它们。
- Ioctx。set_xattr(key, xattr_name, xattr_value)
Ioctx.set_xattr(self, str key: str, str xattr_name: str, bytes xattr_value: bytes) -> bool
- 参数:
key (
str
) -- 要设置xattr的对象名称xattr_name (
str
) -- 要设置的扩展属性xattr_value (
bytes
) -- 扩展属性的值
- Raises:
TypeError
- Raises:
Error
- 返回类型:
bool
- 返回:
成功时为True,否则引发错误
- Ioctx。get_xattrs(oid)
Ioctx.get_xattrs(self, str oid: str) -> XattrIterator
- 参数:
oid (
str
) -- 要从中获取xattrs的对象名称- Raises:
TypeError
- Raises:
Error
- 返回类型:
XattrIterator
- 返回:
XattrIterator
- XattrIterator.__next__()
XattrIterator.__next__(self)
- Raises:
StopIteration
- 返回:
对名和值的对 - 下一个Xattr
- Ioctx。get_xattr(key, xattr_name)
Ioctx.get_xattr(self, str key: str, str xattr_name: str) -> bytes
- 参数:
key (
str
) -- 要从中获取xattr的对象名称xattr_name (
str
) -- 要读取的扩展属性
- Raises:
TypeError
- Raises:
Error
- 返回类型:
bytes
- 返回:
xattr的值
- Ioctx。rm_xattr(key, xattr_name)
Ioctx.rm_xattr(self, str key: str, str xattr_name: str) -> bool
- 参数:
key (
str
) -- 要从中删除xattr的对象名称xattr_name (
str
) -- 要删除的扩展属性
- Raises:
TypeError
- Raises:
Error
- 返回类型:
bool
- 返回:
成功时为True,否则引发错误
对象接口
从I/O上下文中,您可以检索池中的对象列表并迭代它们。对象接口使每个对象看起来像文件,并且您可以对对象执行同步操作。异步操作,您应该使用I/O上下文方法。
- Ioctx。list_objects()
Ioctx.list_objects(self) -> ObjectIterator
- 返回类型:
ObjectIterator
- 返回:
ObjectIterator
- ObjectIterator.__next__()
ObjectIterator.__next__(self)
- Raises:
StopIteration
- 返回:
下一个rados.Ioctx对象
- Object.读取(length=1024 * 1024)
- Object.write(string_to_write)
- Object.get_xattrs()
- Object.get_xattr(xattr_name)
- Object.set_xattr(xattr_name, xattr_value)
- Object.rm_xattr(xattr_name)
- Object.stat()
- Object.删除()
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.