Cassandra 使用手册

ailili

贡献于2012-11-30

字数:0 关键词: NoSQL数据库 手册

Cassandra 使用手册 1、安装与配置 ............................................................................................................................................................. 2 1.1 单机 ................................................................................................................................................................ 2 1.2 集群 ................................................................................................................................................................ 2 2、Cassandra 数据模型 ............................................................................................................................................... 3 2.1 column ............................................................................................................................................................. 3 2.2 super column ................................................................................................................................................... 4 2.3 column family ................................................................................................................................................. 4 2.4 super column family ........................................................................................................................................ 6 3、命令行..................................................................................................................................................................... 8 3.1 cassandra-cli .................................................................................................................................................... 8 3.2 nodetool ........................................................................................................................................................... 9 4、简单的 Java 编程接口 Thrift ................................................................................................................................. 9 4.1 准备工作 ......................................................................................................................................................... 9 4.2 数据库的连接和断开连接 ............................................................................................................................ 9 4.3 插入 ................................................................................................................................................................ 9 4.3.1 单条数据的插入 ................................................................................................................................. 9 4.3.2 批量插入 ........................................................................................................................................... 10 (1)关于 Mutation ........................................................................................................................... 10 (2)batch_mutate ............................................................................................................................. 11 4.4 查询 .............................................................................................................................................................. 11 4.4.1 查询相关的数据类型 ........................................................................................................................ 11 (1)ColumnPath ............................................................................................................................... 11 (2)SliceRange................................................................................................................................. 12 (3)SlicePredicate ............................................................................................................................ 12 4.4.2 查询相关的操作 ................................................................................................................................ 13 (1)get .............................................................................................................................................. 13 (2)get_slice..................................................................................................................................... 13 4.4.3 单个字段的查询 ................................................................................................................................ 13 4.4.4 读取整条数据 .................................................................................................................................... 13 5、Cassandra 测试 ..................................................................................................................................................... 14 6、Tips........................................................................................................................................................................ 14 7、一个 Cassandra 实例(在线交易系统) ............................................................................................................ 14 7.1 数据模型设计 ............................................................................................................................................... 14 7.1.1 Seller .................................................................................................................................................. 15 7.1.2 Buyer .................................................................................................................................................. 16 7.1.3 Product ............................................................................................................................................... 16 7.1.4 ProductCategory ................................................................................................................................. 17 7.1.5 Comment ............................................................................................................................................ 18 7.2 编码实现 ...................................................................................................................................................... 18 7.2.1 修改 keyspace 设置 .......................................................................................................................... 18 7.2.2 建立 eclipse 项目 .............................................................................................................................. 19 7.3.3 向 column family 中 batch_mutate ................................................................................................... 19 7.3.4 向 super column family 中 batch_mutate ......................................................................................... 21 7.3.5 从 Cassandra 中查询数据之 column family .................................................................................... 22 7.3.6 从 Cassandra 中查询数据之 super column family........................................................................... 22 参考文献..................................................................................................................................................................... 22 这里使用的版本是 Cassandra 的 1.1.2。 1、安装与配置 1.1 单机 下载 Cassandra(http://cassandra.apache.org/)然后解压到指定目录,比如/home/lfqy/software/Cassandra。然后 修改配置文件。 Cassandra 的配置文件位于 Cassandra 目录的 conf 文件夹下,我们需要配置的是 cassandra.yaml 和 log4j-server.properties。若你在 conf 里找不到 cassandra.yaml,而是一个 xml 文件,那请去下载最新版的 Cassandra。 (1)log4j-server.properties 需要配置 log4j.appender.R.File 属性,这是 log 文件的路径,我将它配置为 log4j.appender.R.File=/home/lfqy/software/Cassandra/apache-cassandra-1.1.2/log s。注意,这里的路径是“文件”的 路径,不是“目录”的路径。 (2)cassandra.yaml 需要配置较多。 data_file_directories:存放数据库数据文件的目录路径(不是文件路径) data_file_directories: - /home/lfqy/software/Cassandra/data commitlog_directory:存放提交日志的目录路径。 commitlog_directory: /home/lfqy/software/Cassandra/commitlog saved_caches_directory:缓存文件夹路径。 saved_caches_directory: /home/lfqy/software/Cassandra/saved_caches 进行如上配置之后便可以启动 Cassandra 了,cd 到 Cassandra 的 bin 目录下,./cassandra 然后就可以启动 cassandra。这个命令行窗口不能关闭,否则 cassandra 也被关闭了。 如果提示找不到 MX4J,可以忽视,或者去下一个 mx4j-tools.jar 并拷贝在 cassandra 目录下的 lib 文件夹内。 无法跳过的错误通常是环境变量配置不对或配置文件配置错误,按提示解决即可。 1.2 集群 在集群中的每一个节点上按 1.1 的步骤配置好 cassandra 数据库。然后再对每一个节点上的 Cassandra 目录下 的 cassandra.yaml 文件中的参数做响应的修改,即可配置成功。 cluster_name:集群名,所有集群里的节点,这个配置必须相同。1.1.2 中默认为 Test Cluster,可以不加修改。 seeds:这是种子节点。cassandra 是一个 p2p 式的分布式数据库,没有所谓的中心节点。但为了保证节点能 找到集群,你必须告诉它至少一台已经在集群内的节点 IP。这样通过这个节点,它能找到集群内的所有节点。 listen_address:其它节点与自己通信的 IP,这里必须设置为自己的主机 IP。若设置为 localhost 或 127.0.0.1, 则可能其它节点无法与自己通信。 rpc_address:这里设置其它节点上的客户端能否与自己的服务端通信。设置为 0.0.0.0 表示任何节点上的客户 端都可以与自己通信,否则只允许本机客户端与自己通信。 这里以两台机器 A 和 B 示例,它们的 IP 分别为 192.168.20.1 和 192.168.20.2。 A(dog)的配置如下: cluster_name:'Test Cluster' seeds: "192.168.1.101,192.168.1.102,192.168.1.103" listen_address: 192.168.1.101 rpc_address: 0.0.0.0 B(cat)的配置如下: cluster_name:'Test Cluster' seeds: "192.168.1.102,192.168.1.101,192.168.1.103" listen_address: 192.168.1.102 rpc_address: 0.0.0.0 C(rabit)的配置如下: cluster_name:'Test Cluster' seeds: "192.168.1.103,192.168.1.101,192.168.1.102" listen_address: 192.168.1.103 rpc_address: 0.0.0.0 其实 ABC 的 seeds 配置没必要都一样,只要有其中一个配置了对方的 IP,保证他们可以互相通信就可以了。 因此若我们想再加入一台节点 C,则我们只需要在 C 的 seeds 里加上 A 或 B 的 IP 就可以了,A 和 B 的 seeds 不 需要变。但官网推荐 seeds 都配置成一样的,因为这样会更健壮。假如 C 只写了 A 的 IP,那么若 A 断了,则 B 和 C 也断了。因此可以的话,尽量将集群里所有节点的 seeds 配置成一样的。 配置成功之后,在各个节点上启动 Cassandra 数据库,然后利用 nodetool 工具可以查看集群中各个节点的负 载和运行情况。如图 1-1。 图 1-1 2、Cassandra 数据模型 2.1 column column 是 Cassandra 中最小的数据单元。它是一个三元组,包括 name、value 和 timestamp,column 的结构 如图 2-1。 图 2-1 The structure of a column 一个 column 的 JSON 形式实例,如下。 图 2-2 column 的 JSON 实例 column 有一个 timestamp 属性,用来记录该 column 最后一次被更新的时间。这不是一个自动生成的元数据 属性,而是客户端写 column 时必须和 column 的 value 一起提供。不能通过 timestamp 进行查询,它只是用来在 服务器端进行冲突处理。[1] p44 2.2 super column 可以将 Super Column 想象成 Column 的数组,它包含一个 name 和一些相应的 column,一个 super column 的 结构图 2-3。 图 2-3 The basic structure of a super column 一个 super column 的 JSON 实例如图 2-4。 图 2-4 super column 的 JSON 形式 column 和 super column 都是 name与 value的组合,它们之间最大的不同在于 column 的 value 是 java 中的 string 类型,而 supercolumn 的 value 是 column 的 map。 2.3 column family column family 是一个包含了许多 row 结构,可以将其想象成数据库中的表。row 是由 key 以及这个 key 所关 联的 column 组成的。图 2-5 和图 2-6 刻画了 column family 的结构。 图 2-5 A column family 图 2-6 A column family sample 图 2-7 给出了一个 column family 实例的 JSON 形式: 图 2-7 一个 column family 的 JSON 形式 Here we have two column families, Musician and Band. The Musician column family has two rows, “bootsy” and “George”. These two rows have a ragged set of columns associated with them: the bootsy record has two columns (email and instrument), and the george record has only one column. That’s fine in Cassandra. The second column family is Band, and it also has a “george” row, with a column named “pfunk”.[1]p44 图 2-8 也是一个 column family 实例 JSON 的形式。 图 2-8 一个 column family 的 JSON 形式 2.4 super column family columnfamily中的一行是存放的是一些 column 键值对,而 super column family中存放的是 super column family (一些 column 的集合)。因此,对于 column family 中一个值的访问是一个 row key 指向一个 column name 指向 一个 value,而 super column family 中一个值的访问是一个 row key 指向一个 super column name 指向一个 column name 指向一个 value。稍微不同的是,super column family 中仍然包含 column,只不过是 super column。[1]p45 图 2-9 和图 2-10 给出了 super column family 的结构图。 图 2-9 A super column family 图 2-10 A super column family consists of a row key and a number of super columns[2] 通过下面一个例子可以更加清楚地知道 super column family 的结构,图 2-11 是一个 super column family 实例 的 JSON 形式。 图 2-11 一个 super column family 的 JSON 形式 3、命令行 3.1 cassandra-cli 注意:这里的命令都要以“;”结束。 cd 命令切换到 Cassandra 的 bin 目录下,./cassandra-cli 启动 cassandra-cli。 connect localhost/9160;连接本地机器所在的集群 show keyspaces;显示集群中现有的 keyspace use xxxx;进入 keyspace xxxx create column family xxxx;创建 column family xxxx drop keyspace xxxx;删除 keyspace xxxx create keyspace xxxx;创建 keyspace xxxx 3.2 nodetool cd 命令到 Cassandra 的 bin 目录下,./nodetool –h localhost ring 可以查看当前机器所在的集群各个节点的负载 情况。 4、简单的 Java 编程接口 Thrift 4.1 准备工作 这里使用的是最简单的 thrift 编程接口,在 eclipse 环境中进行开发,在 eclipse 中新建一个 Java Project 项目, 选中项目,右键 Properties-》Java Build Path-》Libraries-》Add External Jars 导入一下六个外部 jar 包(在 Cassandra 的 lib 目录下),如图 4-1. 图 4-1 导入的外部 jar 包 接下来的开发就向平常开发 Java 程序一样,只不过可以再代码中使用 thrift 提供的接口访问 Cassandra 数据 库。 4.2 数据库的连接和断开连接 //包装好的socket TTransport tr = new TFramedTransport(new TSocket("127.0.0.1",9160)); TProtocol proto = new TBinaryProtocol(tr); Cassandra.Client client = new Cassandra.Client(proto); tr.open(); if(!tr.isOpen()) { System.out.println("failed to connect server!"); return; } 4.3 插入 4.3.1 单条数据的插入 client.set_keyspace("DEMO");//使用DEMO keyspace ColumnParent parent = new ColumnParent("Student");//column family i=1; String key_user_id = "a"; String k = key_user_id + i;//key long timestamp = System.currentTimeMillis();//时间戳 Column idColumn = new Column(toByteBuffer("id"));//column name idColumn.setValue(toByteBuffer(i + ""));//column value idColumn.setTimestamp(timestamp); client.insert( toByteBuffer(k), parent, idColumn, ConsistencyLevel.ONE); Column nameColumn = new Column(toByteBuffer("name")); nameColumn.setValue(toByteBuffer("student" + i)); nameColumn.setTimestamp(timestamp); client.insert( toByteBuffer(k), parent, nameColumn, ConsistencyLevel.ONE); 4.3.2 批量插入 (1)关于 Mutation A Mutation encapsulates either a column to insert, or a deletion to execute for a key. Like ColumnOrSuperColumn, the two properties are mutually exclusive - you may only set one on a Mutation. Attribute Type Default Required Description column_or_supercolumn ColumnOrSuperColumn n/a N The column to insert in to the key. deletion Deletion n/a N The deletion to execute on the key. 在 Cassandra 中,所有的操作分为两种类型:修改和删除。其中,修改又可以分为插入和修改。我们对 Cassandra 中数据的所有自改都使用 Mutation 来操作。如果是插入新的数据,只需要指定 column_or_supercolumn 字段即可, 如果是要修改现有的数据,也是直接指定 column_or_supercolumn 字段。删除数据指定 deletion 字段即可。[3]p31 Mutation 在 cassandra.thrift 中的定义如下: struct Mutation{ optical ColumnOrSuperColumn column_or_supercolumn, optical Deletion deletion } (2)batch_mutate 1)thrift 中 batch_muate 的定义: void batch_mutate( required string keyspace, required map >>mutation_map, required ConsistencyLevel consistency_level=ONE )throws( InvalidRequestException ire, UnavailableException ue, TimeOutException te ) 批量将 Column 写入 Cassandra 中。 其中 keyspace 为写入的 Keyspace 名称,key 为需要写入 Key 的名称,mutation_map 为需要写入的 Column 或者 SuperColumn 集合,consistency_level 为写入一致性级别。 mutation_map 的 key 为 ColumnFamily 的名称,value 为需要在这个 ColumnFamily 做的修改集合,这个修改 集合包括添加、修改和删除。 如果这个方法没有抛出异常,那么就写入成功了。[3]p39 2)batch_mutate batch_mutate(map>> mutation_map, ConsistencyLevel consiste ncy_level) Executes the specified mutations on the keyspace. mutation_map is a map>>; the outer map maps the key to the inner map, which maps the column family to the Mutation; can be read as: map>>. To be more specific, the outer map key is a row key, the inner map key is the column family name. A Mutation specifies either columns to insert or columns to delete. See Mutation and Deletion above for more details.[4] 4.4 查询 4.4.1 查询相关的数据类型 (1)ColumnPath The ColumnPath is the path to a single column in Cassandra. It might make sense to think of ColumnPath and ColumnParent in terms of a directory structure.[4] Attribute Type Default Required Description column_family string n/a Y The name of the CF of the column being looked up. super_column binary n/a N The super column name. column binary n/a N The column name. 我们可以将 ColumnPath 理解为文件系统中的一个具体文件,如果希望查找某一个 key 对应的 value 中某一 个 column family 的某一个 column 的值,我们需要制定 column family 字段和 column 字段。如果我们希望查找某 一个 super column 中某一个 column 的值,我们不仅需要制定 column_family 字段和 super_column 字段,还需要 指定 column 字段。 (2)SliceRange A SliceRange is a structure that stores basic range, ordering and limit information for a query that will return multiple columns. It could be thought of as Cassandra's version of LIMIT and ORDER BY.[4] Attribute Type Default Required Description start binary n/a Y The column name to start the slice with. This attribute is not required, though there is no default value, and can be safely set to '', i.e., an empty byte array, to start with the first column name. Otherwise, it must be a valid value under the rules of the Comparator defined for the given ColumnFamily. finish binary n/a Y The column name to stop the slice at. This attribute is not required, though there is no default value, and can be safely set to an empty byte array to not stop until count results are seen. Otherwise, it must also be a valid value to the ColumnFamily Comparator. reversed bool false Y Whether the results should be ordered in reversed order. Similar to ORDER BY blah DESC in SQL. When reversed is true, start will determine the right end of the range while finish will determine the left, meaning start must be >= finish. count integer 100 Y How many columns to return. Similar to LIMIT 100 in SQL. May be arbitrarily large, but Thrift will materialize the whole result into memory before returning it to the client, so be aware that you may be better served by iterating through slices by passing the last value of one call in as the start of the next instead of increasing count arbitrarily large. (3)SlicePredicate A SlicePredicate is similar to a mathematic predicate, which is described as "a property that the elements of a set have in common." SlicePredicate's in Cassandra are described with either a list of column_names or a SliceRange.[4] Attribute Type Default Required Description column_names list n/a N A list of column names to retrieve. This can be used similar to Memcached's "multi-get" feature to fetch N known column names. For instance, if you know you wish to fetch columns 'Joe', 'Jack', and 'Jim' you can pass those column names as a list to fetch all three at once. slice_range SliceRange n/a N A SliceRange describing how to range, order, and/or limit the slice. If column_names is specified, slice_range is ignored. 4.4.2 查询相关的操作 (1)get ColumnOrSuperColumn get(binary key, ColumnPath column_path, ConsistencyLevel consistency_l evel) . Get the Column or SuperColumn at the given column_path. If no value is present, NotFoundException is thrown. (This is the only method that can throw an exception under non-failure conditions.) .[4] (2)get_slice list get_slice(binary key, ColumnParent column_parent, SlicePredicate pr edicate, ConsistencyLevel consistency_level) Get the group of columns contained by column_parent (either a ColumnFamily name or a ColumnFamily/SuperColumn name pair) specified by the given SlicePredicate struct.[4] 4.4.3 单个字段的查询 //读取某条数据的单个字段 ColumnPath path = new ColumnPath("Student");//设置读取Student的数据 path.setColumn(toByteBuffer("id")); //读取id String key3 = "a1";//读取key为a1的那条记录 System.out.println(toString(client.get(toByteBuffer(key3), path, ConsistencyLevel.ONE).column.value)); 4.4.4 读取整条数据 可以将一行中所有的 column 全部读取出来。 SlicePredicate predicate = new SlicePredicate(); SliceRange sliceRange = new SliceRange(toByteBuffer(""), toByteBuffer(""), false, 10); predicate.setSlice_range(sliceRange); List results =client.get_slice(toByteBuffer(key3), parent, predicate, ConsistencyLevel.ONE); for (ColumnOrSuperColumn result : results) { Column column = result.column; System.out.println(toString(column.name) + " -> " + toString(column.value)); } 5、Cassandra 测试 测试中首先对包含有 100m 的 idcode.record 进行插入数据测试,结果 TimeOutException,原因可能是由于数 据量太大,导致单条数据的插入耗时超过 10000ms,而在 Cassandra 的配置文件 cassandra.yaml 中,有设置 rpc_timeout_in_ms: 10000,也就是说,当一个操作耗时超过 10000ms 时,会造成 TimeOutException。 接下来,选取了数据量较小的 idcode.1m 和 dblp.record 进行测试结果如表 5-1。 包含的记 录数 全部导入所 需时间 插入一条 记录所需时间 查找一条记录所 需时间 idcode.1m 1m 626449ms≈10min 10ms 57ms/35ms dblp.record 3m 6898555ms≈2h 17ms 25ms/14ms 表 5-1 6、Tips 1、I'm dubious that tool support would help a great deal with this, since a Cassandra schema needs to reflect the queries that you want to run, rather than just being a generic model of your domain. http://stackoverflow.com/questions/5916244/what-is-a-good-bulk-data-loading-tool-for-cassandra 7、一个 Cassandra 实例(在线交易系统) 共买卖双方使用 卖家出售产品,可以根据产品的种类进行分类,并且按上架先后顺序排序。 买家可以对产品进行评价,评价也是按照时间先后顺序排序 买家属性:用户名,姓名,年龄,性别,买家地址 卖家属性:用户名,姓名,年龄,性别,卖家地址 产品属性:卖家用户名,产品名称,产品描述,产品价格 评论属性:买家用户名,评论内容 系统中需要四类实体对象:买家,卖家,产品和评论 买家可以添加评论,买家可以分类添加产品 7.1 数据模型设计 根据需求分析,系统需要为每一个实体对象建立一个响应的 column family。同时也要注意到两个特殊的实 体对象:产品和评论。它们不仅包含有自身的固有属性,同时也包含了与其他实体对象的关系,如评论和买家的 关系,以及买家和产品分类的关系。要维护实体之间的关系,我们可以通过 super column family 和单独的 column 选 项 数 据集 family 来实现。 本系统的数据模型由 5 个 column family 组成:Seller、Buyer、Product、ProductCategory 和 Comment。 7.1.1 Seller 7.1.2 Buyer 7.1.3 Product Product 用于保存产品信息,由于产品要在产品分类中根据产品上架的时间排序,所以我们使用 TimeUUID 作为 column family 的 key,该产品的每一个属性都用一个 column 来存储。其中 column 的名称为响应属性的名称, column 的值为响应属性的值。 7.1.4 ProductCategory ProductCategory 用于保存产品的分类信息,产品类别的名称作为 column family 的 key,该产品分类下的每一 个产品用一个 column 来存储。其中 column 的名称为相应的 TimeUUID,column 的值为空。同时要求在产品分类 下产品按上架的时间排序,所以 column family 选用的排序规则为 TimeUUIDType。 7.1.5 Comment Comment 用于保存评论的信息,super column family 的 key 被评论产品的 TimeUUID,super column 的名称 为评论自身的 TimeUUID,同时要求评论按照时间排序,所以 super column 选用的排序规则为 TimeUUIDType。 supercolumn 下的每一个 column 用来存储评论的相应属性,其中 column 的名称为响应属性的名称,column 的值 为相应属性的值。 Comment 在 Cassandra 中的配置如下: 当有数据存储的时候: 7.2 编码实现 7.2.1 修改 keyspace 设置 其实,这些可以通过 cassandra-cli 来完成。 7.2.2 建立 eclipse 项目 建立了四个包: cassSeller.app:测试应用逻辑 cassSeller.dao:操作 Cassandra 的接口定义 cassSeller.dao.impl:操作 Cassandra 的接口实现 cassSeller.model:实体对象定义 7.3.3 向 column family 中 batch_mutate //第一个 Map:键为 row key;值为一个 Mutation 的一个 Map Map>> mutationMap = new HashMap>>(); //第二个 Map:键为 column family 的名称;值为一个 Mutation 的 List Map> cfMutationMap = new HashMap>(); //一个 List,存放着许多 Mutation,也就是存放了放在一起的一些 column List mutationList = new ArrayList(); //下面的 4 个 if 语句块是将 product 的相关属性分别组织成 mutation,并加入到 mutationList //价格 if (product.getPrice() > 0) { Column c = new Column(); c.name = "price".getBytes("utf-8"); c.value = String.valueOf(product.getPrice()).getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); cosc.column = c; Mutation mutation = new Mutation(); mutation.column_or_supercolumn = cosc; mutationList.add(mutation); } //desc 是 description 的简写,意思是产品描述 if (product.getDesc() != null && !product.getDesc().isEmpty()) { Column c = new Column(); c.name = "desc".getBytes("utf-8"); c.value = product.getDesc().getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); cosc.column = c; Mutation mutation = new Mutation(); mutation.column_or_supercolumn = cosc; mutationList.add(mutation); } //名称 if (product.getName() != null && !product.getName().isEmpty()) { Column c = new Column(); c.name = "name".getBytes("utf-8"); c.value = product.getName().getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); cosc.column = c; Mutation mutation = new Mutation(); mutation.column_or_supercolumn = cosc; mutationList.add(mutation); } //卖家名称 if (product.getSellerUserName() != null && !product.getSellerUserName().isEmpty()) { Column c = new Column(); c.name = "sellerUserName".getBytes("utf-8"); c.value = product.getSellerUserName().getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); cosc.column = c; Mutation mutation = new Mutation(); mutation.column_or_supercolumn = cosc; mutationList.add(mutation); } //将信息组织成适合提交的格式 if (!mutationList.isEmpty()) { //将 mutationList 作为值放入第二个 map,其中键为 column 所在的 column family 的名称 cfMutationMap.put(Product.ColumnFamily, mutationList); //将第二个 map 作为值放入第一个 map,其中键为这些 column 所在的 row 的 row key mutationMap.put(product.getUuid().toString(), cfMutationMap); //从客户端提交到 Cassandra cassandraClient.batch_mutate(Product.keySpace, mutationMap, ConsistencyLevel.ONE); } 7.3.4 向 super column family 中 batch_mutate //第一个 Map:键为 row key;值为一个 Mutation 的一个 Map Map>> mutationMap = new HashMap>>(); //第二个 Map:键为 column family 的名称;值为一个 Mutation 的 List Map> cfMutationMap = new HashMap>(); //一个 List,存放着许多 Mutation,也就是存放了放在一起的一些 super column List mutationList = new ArrayList(); //一个 column 的 List,存放着许多放在一个 super column 里面的 column List columns = new ArrayList(); //下面的两个 if 语句块分别将评论的用户名和评论的内容组织成 column 并添加到一个 column 的 List //评论的用户名 if (comment.getCommentUserName() != null && !comment.getCommentUserName().isEmpty()) { Column c = new Column(); c.name = "commentUserName".getBytes("utf-8"); c.value = comment.getCommentUserName().getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); columns.add(c); } //评论的内容 if (comment.getContent() != null && !comment.getContent().isEmpty()) { Column c = new Column(); c.name = "content".getBytes("utf-8"); c.value = comment.getContent().getBytes("utf-8"); c.timestamp = System.currentTimeMillis(); columns.add(c); } if (!columns.isEmpty()) { //新建一个 super column,其中存放 List columns 中存放的 column SuperColumn sc = new SuperColumn(); sc.name = comment.getUuid().toByteArray(); sc.columns = columns; //通过 ColumnOrSuperColumn 将这个 super column 组织进 Mutation ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); cosc.super_column = sc; Mutation mutation = new Mutation(); mutation.column_or_supercolumn = cosc; //将这个 Mutation 加入到 mutationList mutationList.add(mutation); //将 mutationList 作为值放入第二个 map,其中键为该 super column 所在的 super column family 的名称 cfMutationMap.put(Comment.ColumnFamily, mutationList); //将第二个 map 作为值放入第一个 map,其中键为这些 super column 所在的 row 的 row key mutationMap.put(productUUID.toString(), cfMutationMap); //从客户端提交到 Cassandra cassandraClient.batch_mutate(Product.keySpace, mutationMap, ConsistencyLevel.ONE); } 7.3.5 从 Cassandra 中查询数据之 column family 7.3.6 从 Cassandra 中查询数据之 super column family 参考文献 【1】 Cassandra Definitive Guide 【2】 http://en.wikipedia.org/wiki/Super_column_family 【3】 Cassandra 实战 【4】 http://wiki.apache.org/cassandra/API

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ] 4 人已下载

下载文档

相关文档