注意

本文档适用于 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

管理池

连接到集群时,的RadosAPI允许您管理池。您可以列出池,检查池是否存在,创建池并删除池。

 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) -> Versionlibradosa元组

返回类型:

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) - 对象数量

class rados。Rados
require_state(*args)

检查Rados对象是否处于特殊状态

参数:

args-- 作为单独的参数检查任何数量的状态

Raises:

RadosStateError

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. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.