分布式 Key-Value 存储系统:Cassandra 入门

Cassandra分析 一、 简介 Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由Facebook开发,用于储存特别大的数据。Facebook目前在使用此系统。 主要特性: 分布式 基于column的结构化 高伸展性 Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra 的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能 阅读详情

简介: Apache Cassandra 是一套开源分布式 Key-Value 存储系统。它最初由 Facebook 开发,用于储存特别大的数据。 Cassandra 不是一个数据库,它是一个混合型的非关系的数据库,类似于 Google 的 BigTable。本文主要从以下五个方面来介绍 Cassandra:Cassandra 的数据模型、安装和配制 Cassandra、常用编程语言使用 Cassandra 来存储数据、Cassandra 集群搭建。


 

Cassandra 的数据存储结构

Cassandra 的数据模型是基于列族(Column Family)的四维或五维模型。它借鉴了 Amazon 的 Dynamo 和 Google's BigTable 的数据结构和功能特点,采用 Memtable 和 SSTable 的方式进行存储。在 Cassandra 写入数据之前,需要先记录日志 ( CommitLog ),然后数据开始写入到 Column Family 对应的 Memtable 中,Memtable 是一种按照 key 排序数据的内存结构,在满足一定条件时,再把 Memtable 的数据批量的刷新到磁盘上,存储为 SSTable 。

图 1. Cassandra 的数据模型图:

  1. Cassandra 的数据模型的基本概念:
  2. 1. Cluster : Cassandra 的节点实例,它可以包含多个 Keyspace
    2. Keyspace : 用于存放 ColumnFamily 的容器,相当于关系数据库中的 Schema 或 database3. ColumnFamily : 用于存放 Column 的容器,类似关系数据库中的 table 的概念 4. SuperColumn :它是一个特列殊的 Column, 它的 Value 值可以包函多个 Column5. Columns:Cassandra 的最基本单位。由 name , value , timestamp 组成

下面是关于数据模型实例分析 :


图 2. 数据模型实例分析
图 2. 数据模型实例分析 

Cassandra 节点的安装和配置

获取 Cassandra

 # wget  http://labs.renren.com/apache-mirror/cassandra/0.6.0/apache- 
 cassandra-0.6.0-rc1-bin.tar.gz 
 # tar -zxvf apache-cassandra-0.6.0-rc1-bin.tar.gz 
 # mv  apache-cassandra-0.6.0-rc1 cassandra 
 # ls Cassandra 


Cassandra 的目录说明
bin存放与 Cassandra 操作的相关脚本
conf存放配置文件的目录
interfaceCassandra 的 Thrift 接口定义文件,可以用于生成各种编程语言的接口代码
Javadoc源代码的 javadoc
libCassandra 运行时所需的 jar 包

配制 Cassandra 节点的数据存储目录和日志目录

修改配制文件 storage-conf.xml:


默认的内容
				
 <CommitLogDirectory>/var/lib/cassandra/commitlog</CommitLogDirectory> 
	 <DataFileDirectories> 
 <DataFileDirectory>/var/lib/cassandra/data</DataFileDirectory> 
	 </DataFileDirectories> 


配置后的内容
				
	 <CommitLogDirectory>/data3/db/lib/cassandra/commitlog</CommitLogDirectory> 
	 <DataFileDirectories> 
 <DataFileDirectory>/data3/db/lib/cassandra/data</DataFileDirectory> 
	 </DataFileDirectories> 


修改日志配制文件 log4j.properties:


log4j.properties 配置
				
 # 日志路径
 #log4j.appender.R.File=/var/log/cassandra/system.log 
 # 配置后的日志路径 : 
 log4j.appender.R.File=/data3/db/log/cassandra/system.log 


创建文件存放数据和日志的目录

 # mkdir – p /data3/db/lib/cassandra 
 # mkdir – p /data3/db/log/Cassandra 

配制完成后,启动 Cassandra

 # bin/Cassandra 


显示信息

 INFO 09:29:12,888 Starting up server gossip 
 INFO 09:29:12,992 Binding thrift service to localhost/127.0.0.1:9160 

看到这两行启动回显信息时,说明 Cassandra 已启动成功。

连接到 Cassandra 并添加、获取数据

Cassandra 的 bin 目录已自带了命令行连接工具 cassandra-cli,可使用它连接到 Cassandra,并添加、读取数据。


连接到 Cassandra,并添加、读取数据
				
 # bin/cassandra-cli --host localhost --port 9160 
 Connected to: "Test Cluster" on localhost/9160 
 Welcome to cassandra CLI. 
 Type 'help' or '?' for help. Type 'quit' or 'exit' to quit. 
 cassandra> 
 cassandra> set Keyspace1.Standard2['studentA']['age'] = '18'
 Value inserted 
 cassandra> get Keyspace1.Standard2['studentA'] 
 => (column=age, value=18, timestamp=1272357045192000) 
 Returned 1 results   

停止 Cassandra 服务


查出 Cassandra 的 pid:16328
				
 # ps -ef | grep cassandra 
 # kill 16328 

Cassandra 配制文件 storage-conf.xml 相关配制介绍


清单 1. storage-conf.xml 节点配制说明清单
				
 <!-- 集群时显示的节点名称 --> 
 <ClusterName>Test Cluster</ClusterName> 
 <!-- 节点启动时,是否自动加入到集群中,默认为 false --> 
 <AutoBootstrap>false</AutoBootstrap> 
 <!-- 集群的节点配制 --> 
 <Seeds> 
 <Seed>127.0.0.1</Seed> 
 </Seeds> 
 <!-- 节点之间通迅的监听地址 --> 
 <ListenAddress>localhost</ListenAddress> 
 <!-- 
      基于 Thrift 的 cassandra 客户端监听地址,
集群时设为:0.0.0.0 表示侦听所有客户端 , 默认为:localhost 
 --> 
 <ThriftAddress>localhost</ThriftAddress> 
 <!-- 客户端连接的端口 --> 
 <ThriftPort>9160</ThriftPort> 
 <!-- 
   FlushDataBufferSizeInMB   将 memtables 上的数据写入在 Disk 上,
超过设定好的限制大小时 ( 默认 32M),则将数据写入磁盘,
   FlushIndexBufferSizeInMB  超过设定的时长(默认 8 分钟)后,
将 memtables 由的数据写入磁盘中
 --> 
 <FlushDataBufferSizeInMB>32</FlushDataBufferSizeInMB> 
 <FlushIndexBufferSizeInMB>8</FlushIndexBufferSizeInMB> 
 <!-- 
 节点之间的日志记录同步模式。
 默认:periodic, 对应配制 CommitLogSyncPeriodInMS 
 启动 batch 时,则对应的配制 CommitLogSyncBatchWindowInMS 
 --> 
 <CommitLogSync>periodic</CommitLogSync> 
 <!-- 	默认为每 10 秒同步一次日志记录 --> 
 <CommitLogSyncPeriodInMS>10000</CommitLogSyncPeriodInMS> 
 <!-- 
 <CommitLogSyncBatchWindowInMS>1</CommitLogSyncBatchWindowInMS> --> 


常用编程语言使用 Cassandra 来存储数据

在使用 Cassandra 时,通常情况下都需要使用第三方插件 Thrift 来生成与 Cassandra 相关的库文件 , 您可以在 http://incubator.apache.org/thrift 下载此插件,并学习它的使用方法。以下是分别在 Java、PHP、Python、C#、Ruby 五种常用编程语言中使用 Cassandra:

Java 程序使用 Cassandra

把 libthrift-r917130.jar,apache-cassandra-0.6.0-rc1.jar 加入到 Eclipse 的编译路径中。

建立数据库连接:使用 libthrift-r917130.jar 的 TTransport 的 open 方法建立起与 Cassandra 服务端 (IP:192.168.10.2 端口:9160) 的连接。

数据库操作:使用 Cassandra.Client 创建一个客户端实例。调用 Client 实例的 insert 方法写入数据,通过 get 方法获取数据。

关闭数据库连接:使用 TTransport 的 close 方法断开与 Cassandra 服务端的连接。


清单 2. Java 连接 Cassandra,写入并读取数据。
				
 package com.test.cassandra;| 
 import java.io.UnsupportedEncodingException; 
 import org.apache.thrift.transport.TTransport; 
 import org.apache.thrift.transport.TSocket; 
 import org.apache.thrift.protocol.TProtocol; 
 import org.apache.thrift.protocol.TBinaryProtocol; 
 import org.apache.thrift.TException; 
 import org.apache.cassandra.thrift.Cassandra; 
 import org.apache.cassandra.thrift.Column; 
 import org.apache.cassandra.thrift.ColumnOrSuperColumn; 
 import org.apache.cassandra.thrift.ColumnPath; 
 import org.apache.cassandra.thrift.ConsistencyLevel; 
 import org.apache.cassandra.thrift.InvalidRequestException; 
 import org.apache.cassandra.thrift.NotFoundException; 
 import org.apache.cassandra.thrift.TimedOutException; 
 import org.apache.cassandra.thrift.UnavailableException; 
 /* 
 * 使 Java 客户端连接 Cassandra 并进行读写操作
 * @author jimmy 
 * @date 2010-04-10 
 */ 
 public class JCassandraClient{ 
 public static void main(String[] args) throws InvalidRequestException, 
 NotFoundException, UnavailableException, TimedOutException, 
 TException, UnsupportedEncodingException { 

 // 建立数据库连接
 TTransport tr = new TSocket("192.168.10.2", 9160); 
 TProtocol proto = new TBinaryProtocol(tr); 
 Cassandra.Client client = new Cassandra.Client(proto); 
 tr.open(); 
 String keyspace = "Keyspace1"; 
 String cf = "Standard2"; 
 String key = "studentA"; 
 // 插入数据
 long timestamp = System.currentTimeMillis(); 
 ColumnPath path = new ColumnPath(cf); 
 path.setColumn("age".getBytes("UTF-8")); 
 client.insert(keyspace,key,path,"18".getBytes("UTF-8"), 
 timestamp,ConsistencyLevel.ONE); 
 path.setColumn("height".getBytes("UTF-8")); 
 client.insert(keyspace,key,path,"172cm".getBytes("UTF-8"), 
 timestamp,ConsistencyLevel.ONE); 
 // 读取数据
 path.setColumn("height".getBytes("UTF-8")); 
 ColumnOrSuperColumn cc = client.get(keyspace, key, path, ConsistencyLevel.ONE); 
 Column c = cc.getColumn(); 
 String v = new String(c.value, "UTF-8"); 
        // 关闭数据库连接
 tr.close(); 
 } 
 } 

PHP 程序使用 Cassandra

在 PHP 代码中使用 Cassandra,需要借助 Thrift 来生成需要的 PHP 文件,通过使用 thrift --gen php interface/cassandra.thrift 生成所需要的 PHP 文件,生成的 PHP 文件中提供了与 Cassandra 建立连接、读写数据时所需要的函数。


清单 3. PHP 连接 Cassandra,写入并读取数据。
				
 <?php 
 $GLOBALS['THRIFT_ROOT'] = '/usr/share/php/Thrift'; 
 require_once 
 $GLOBALS['THRIFT_ROOT'].'/packages/cassandra/Cassandra.php'; 
 require_once 
 $GLOBALS['THRIFT_ROOT'].'/packages/cassandra/cassandra_types.php'; 
 require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php'; 
 require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php'; 
 require_once 
 $GLOBALS['THRIFT_ROOT'].'/transport/TFramedTransport.php'; 
 require_once 
 $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php'; 
 try { 
 // 建立 Cassandra 连接
 $socket = new TSocket('192.168.10.2', 9160); 
 $transport = new TBufferedTransport($socket, 1024, 1024); 
 $protocol = new TBinaryProtocolAccelerated($transport); 
 $client = new CassandraClient($protocol); 
 $transport->open(); 
 $keyspace = 'Keyspace1'; 
 $keyUser = "studentA"; 
 $columnPath = new cassandra_ColumnPath(); 
 $columnPath->column_family = 'Standard1'; 
 $columnPath->super_column = null; 
 $columnPath->column = 'age'; 
 $consistency_level = cassandra_ConsistencyLevel::ZERO; 
 $timestamp = time(); 
 $value = "18"; 
 // 写入数据
 $client->insert($keyspace, $keyUser, $columnPath, $value, 
                            $timestamp, $consistency_level); 
 $columnParent = new cassandra_ColumnParent(); 
 $columnParent->column_family = "Standard1"; 
 $columnParent->super_column = NULL; 
 $sliceRange = new cassandra_SliceRange(); 
 $sliceRange->start = ""; 
 $sliceRange->finish = ""; 
 $predicate = new cassandra_SlicePredicate(); 
 list() = $predicate->column_names; 
 $predicate->slice_range = $sliceRange; 
 $consistency_level = cassandra_ConsistencyLevel::ONE; 
 $keyUser = studentA; 
 // 查询数据
 $result = $client->get_slice($keyspace, $keyUser, $columnParent, 
             $predicate, $consistency_level); 
 // 关闭连接
 $transport->close(); 
 } catch (TException $tx) { 
 }?> 

Python 程序使用 Cassandra

在 Python 中使用 Cassandra 需要 Thrift 来生成第三方 Python 库,生成方式: thrift --gen py interface/cassandra.thrift, 然后在 Python 代码中引入所需的 Python 库,生成的 Python 库提供了与 Cassandra 建立连接、读写数据时所需要的方法。


清单 4. Python 连接 Cassandra,写入并读取数据。
				
 from thrift import Thrift 
 from thrift.transport import TTransport 
 from thrift.transport import TSocket 
 from thrift.protocol.TBinaryProtocol import 
 TBinaryProtocolAccelerated 
 from cassandra import Cassandra 
 from cassandra.ttypes import * 
 import time 
 import pprint 
 def main(): 
 socket = TSocket.TSocket("192.168.10.2", 9160) 
 transport = TTransport.TBufferedTransport(socket) 
 protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport) 
 client = Cassandra.Client(protocol) 
 pp = pprint.PrettyPrinter(indent=2) 
 keyspace = "Keyspace1"
 column_path = ColumnPath(column_family="Standard1", column="age") 
 key = "studentA"
 value = "18 "
 timestamp = time.time() 
 try: 
 # 打开数据库连接
 transport.open() 
 # 写入数据
 client.insert(keyspace,key,column_path, 
 value,timestamp,ConsistencyLevel.ZERO) 
 # 查询数据
 column_parent = ColumnParent(column_family="Standard1") 
 slice_range = SliceRange(start="", finish="") 
 predicate = SlicePredicate(slice_range=slice_range) 
 result = client.get_slice(keyspace,key,column_parent, 
 predicate,ConsistencyLevel.ONE) 
 pp.pprint(result) 
 except Thrift.TException, tx: 
 print 'Thrift: %s' % tx.message 
 finally: 
 # 关闭连接
 transport.close() 
 if __name__ == '__main__': 
 main() 


C# 使用 Cassandra

在 C# 中使用 Cassandra 需要 Thrift.exe 来生成动态链接库,使用 ./thrift.exe --gen csharp interface/cassandra.thrift 生成所需要的 DLL 文件,生成的 DLL 提供了与 Cassandra 建立连接,读写数据等所需的类和方法,在编程环境中引入生成的 DLL,即可使用。


清单 5. C# 连接 Cassandra,写入并读取数据。
				
 namespace CshareCassandra{ 
 using System; 
 using System.Collections.Generic; 
 using System.Diagnostics; 
 using Apache.Cassandra; 
 using Thrift.Protocol; 
 using Thrift.Transport; 
 class CassandraClient{ 
 static void Main(string[] args){ 
 // 建立数据库连接
 TTransport transport = new TSocket("192.168.10.2", 9160); 
 TProtocol protocol = new TBinaryProtocol(transport); 
 Cassandra.Client client = new Cassandra.Client(protocol); 
 transport.Open(); 
 System.Text.Encoding utf8Encoding = System.Text.Encoding.UTF8; 
 long timeStamp = DateTime.Now.Millisecond; 
 ColumnPath nameColumnPath = new ColumnPath(){ 
 Column_family = "Standard1", 
 Column = utf8Encoding.GetBytes("age")}; 
   // 写入数据
 client.insert("Keyspace1","studentA",nameColumnPath, 
 utf8Encoding.GetBytes("18"),timeStamp, ConsistencyLevel.ONE); 
 // 读取数据
 ColumnOrSuperColumn returnedColumn = client.get("Keyspace1", 
            "studentA", nameColumnPath, ConsistencyLevel.ONE); 
        Console.WriteLine("Keyspace1/Standard1: age: {0}, value: {1}", 
                     utf8Encoding.GetString(returnedColumn.Column.Name), 
                     utf8Encoding.GetString(returnedColumn.Column.Value)); 
 // 关闭连接
 transport.Close(); 
 } 
 }} 


Ruby 使用 Cassandra

在 Ruby 中使用 Cassandra 需要先安装 gem,安装命令:gem install cassandra

安装完成后,打开 Ruby 的 irb 开始使用 Cassandra。


清单 6. Ruby 连接 Cassandra,写入并读取数据
				
 > require 'rubygems' 
 > require 'cassandra'
 # 建立数据库连接 
 > cdb = Cassandra.new('Keyspace1',"192.168.10.1:9160", :retries => 3) 
 # 写入数据
 > cdb.insert(:Standard1, 'studentA', {'age' => '18'}) 
 # 读取数据
 > cdb.get(:Standard1, :studentA) 
 # 关闭连接
 > cdb.disconnect 

搭建 Cassandra 集群环境

Cassandra 的集群是没有中心节点的,各个节点的地位完全相同,节点之间是通过 gossip 的协议来维护集群的状态。


以下是两台安装了 Linux 系统的服务器,且初步设置了 Cassandra 环境和启用了端口 7000,9160:
服务器名端口IP 地址
ServiceA7000,9160192.168.10.3
ServiceB7000,9160192.168.10.2

配制服务器 ServiceA、ServiceB 的 storage-conf.xml 文件


ServiceA 的配置
				
 <Seeds> 
 <Seed>192.168.10.3</Seed> 
 </Seeds> 
 <ListenAddress>192.168.10.2</ListenAddress> 
 <ThriftAddress>0.0.0.0</ThriftAddress> 



ServiceB 的配置
				
 <Seeds> 
 <Seed>192.168.10.3</Seed> 
 <Seed>192.168.10.2</Seed> 
 </Seeds> 
 <ListenAddress>192.168.10.2</ListenAddress> 
 <ThriftAddress>0.0.0.0</ThriftAddress> 


配制完成后,分别启动 ServiceA 和 ServiceB 上的 Cassandra 服务。

查看 ServiceA 和 ServiceB 是否集群成功,可使用 Cassandra 自带的客户端命令

 bin/nodetool --host 192.168.10.2 ring 


集群成功则会返回以下类似信息:
				
 Address Status Load Range Ring 
                                       106218876142754404016344802054916108445 
 192.168.10.2  Up         2.55 KB       31730917190839729088079827277059909532     |<--| 
 192.168.10.3  Up         3.26 KB       106218876142754404016344802054916108445    |-->| 

使用 Cassandra 命令行工具进行集群测试

从 ServiceB 连接到 ServiceA,可使用命令:

 cassandra-cli -host 192.168.10.3 -port 9160 



集群测试一
				
写入集群数据
 ServiceA 连接到 ServiceA: 

 # set Keyspace1.Standard2['studentAA']['A2A'] = 'a2a'

 ServiceB 连接到 ServiceA: 

 # set Keyspace1.Standard2['studentBA']['B2A'] = 'b2a'

 ServiceA 连接到 ServiceB: 
 # set Keyspace1.Standard2['studentAB']['A2B'] = 'a2b'

获取集群数据:

 ServiceA 连接到 ServiceA : 
 # get Keyspace1.Standard2['studentAA'], 
   get Keyspace1.Standard2['studentBA'], 
    get Keyspace1.Standard2['studentAB'] 

 ServiceB 连接到 ServiceA : 
 # get Keyspace1.Standard2['studentAA'], 
    get Keyspace1.Standard2['studentBA'], 
    get Keyspace1.Standard2['studentAB'] 

 ServiceA 连接到 ServiceB : 
 # get Keyspace1.Standard2['studentAA'], 
  get Keyspace1.Standard2['studentBA'], 
  get Keyspace1.Standard2['studentAB'] 


清单 8. 集群测试清单二

ServiceA 停止 Cassandra 服务,ServiceA 连接到 ServiceB 并写入数据

 # set Keyspace1.Standard2['studentAR']['A2R'] = 'a2R'

启动 ServiceA,并链接到 ServiceA 本身,读取刚才在 ServiceB 写入的数据

 # bin/cassandra-cli -host 192.168.10.3 -port 9160 
 # get Keyspace1.Standard2['studentAR'] 


总结

以上我们介绍了 Cassandra 的数据模型、节点安装和配置、常用编程语言中使用 Cassandra 以及 Cassandra 的集群和测试。Cassandra 是一个高性能的 P2P 去中心化的非关系型数据库,可以分布式进行读写操作。在系统运行时可以随意的添加或删降字段,是 SNS 应用的理想数据库。


 


参考资料

关于作者

黄俊平,擅长Java应用程序的架构、设计和实现,热衷开源软件的开发和应用,活跃在开源中国社区 (http://www.oschina.net),您可以通过博客(http://www.itsmile.net/blog)或者邮件(ideajava@gmail.com)来联系他。

Cassandra数据库从入门到精通系列之四:连接Cassandra数据库、创建键空间、使用键空间、创建表、插入数据 Cassandra数据库从入门到精通系列之三:连接Cassandra数据库、创建键空间、使用键空间、创建表、插入数据 阅读详情

相关推荐

Cassandra数据库连接与Java驱动实战

通过本篇博客,我们学习了如何使用DataStax Java驱动连接Cassandra数据库,并执行基本的查询操作。Cassandra的灵活性和扩展性使其成为处理大规模数据集的理想选择。希望这篇博客能够帮助你快速上手Cassandra数据库的开发。给Kimi加油。

m0_62153576的博客 755

探秘C驱动器:连接Apache Cassandra的高效工具

探秘C#驱动器:连接Apache Cassandra的高效工具 csharp-driverdatastax/csharp-driver: 一个基于 C# 的 Apache Cassandra 数据库驱动程序。适合在 C# 项目中需要访问 Cassandra 数据库的场景,提供了一些简单易用的 API,可以实现高效的数据库访问和操作。项目地址:https://gitcode.com/gh_mirr...

gitblog_00090的博客 767

Scylladb或Cassandra客户端工具DevCenter

Scylladb或Cassandra 客户端工具 DevCenter

Apache Flink Cassandra 连接器使用指南

Apache Flink Cassandra 连接器使用指南 项目介绍 Apache Flink Cassandra 连接器是Apache Flink官方提供的一个组件,它允许Flink应用程序高效地读写数据到Apache Cassandra数据库中。Flink作为一个强大的开源流处理框架,支持流处理和批处理,而此连接器则扩展了其能力,使之能够轻松集成Cassandra,实现数据的实时存储和检索...

gitblog_01130的博客 477

LSM6DS3TR-C IMU传感器入门:从MEMS原理到姿态解算实战

惯性测量单元(IMU)是现代智能设备实现运动感知的核心部件,其基础原理基于微机电系统(MEMS)技术。MEMS加速度计通过检测质量块在惯性力作用下的位移来测量线性加速度,而陀螺仪则利用科里奥利力效应感知角速度。这种技术使得微型化、低成本的6自由度运动测量成为可能,为机器人、无人机、可穿戴设备等提供了关键的空间姿态和运动状态信息。在实际工程中,开发者需要掌握I2C/SPI通信协议、传感器数据读取与校准,并通过互补滤波等算法融合加速度计和陀螺仪数据,实现稳定的姿态解算。LSM6DS3TR-C作为一款高性价比的6

weixin_28684655的博客 595

手把手推导APM的 sqrt_controller控制器

前言 玩过无人机的朋友对APM应该都不会陌生,如果是搞过多旋翼飞控且读过代码,肯定遇到过sqrt_controller控制器,它频繁的在位置、姿态控制中出现,所以非常有必要搞清楚这个控制原理。 下面以高度控制器为例来分析。 高度控制 APM的高度控制采用PID串级3环控制,即外环位置控制,中间速度控制,内环速度控制,如下图所示。 今天要讨论的sqrt_controller就是应用于位置控制器中。位置控制器的输出是速度控制器的参考reference输入,如果采用单P控制,其输出vel_ref = pos_e

周小逗的博客 3027

Key-Value存储系统简介

Redis是一个Key-Value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是...

weixin_33810006的博客 1088

一个固定翼飞机仿真程序带你系统性上手如何实现配平(工具箱+脚本)

老规矩,该博客所用的模型和脚本已上传至百度网盘,名字为“固定翼配平训练例子”,自己自取。

zouxu634866的博客 2566

Redis实践_Key-Value存储系统

Key-Value存储系统简介:          Key-Value Store是当下比较流行的话题,尤其在构建诸如搜索引擎、IM、P2P、游戏服务器、SNS等大型互联网应用以及提供云计算服务的时候,怎样保证系统在海量数据环境下的高性能、高可靠性、高扩展性、高可用性、低成本以及数据库服务器的性能瓶颈应用而生的。        按照分布式领域的CAP理论(Consistency、 Availab...

依着风睡的博客 2518

Mann-Kendall检验全解析:从原理到11种变体及Python实现

本文全面解析Mann-Kendall检验,从基础原理到应对自相关、季节性等复杂数据的11种关键变体,如Hamed-Rao修正、季节性MK和趋势自由预白化(TFPW)。详细阐述各方法的适用场景与数学原理,并提供完整的Python实战代码,帮助研究者针对不同数据特性选择最稳健的趋势分析方法。

weixin_29050271的博客 457

Chrome下载B站视频字幕的插件

本文主要介绍了Chrome下载B站视频字幕的插件,希望能对使用Chrome的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 3万+

cassandra-分布式Key-Value存储系统

Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由Facebook开发,用于储存特别大的数据。Facebook目前在使用此系统。主要特性:分布式基于column的结构化高伸展性Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra 的一个写操作,会被

yu_taiji的专栏 394

【23】OpenCV C++实战篇——张正友相机标定【相机标定原理、相机标定流程、标定结果评价、图像畸变矫正】

R是3×3的正交单位矩阵(即旋转矩阵),t为平移向量,R、t与摄像机无关,所以称这两个参数为摄像机的外参数(extrinsicparameter),可以理解为两个坐标原点之间的距离,因其受x,y,z三个方向上的分量共同控制,所以其具有三个自由度。R是3×3的正交单位矩阵(即旋转矩阵),t为平移向量,R、t与摄像机无关,所以称这两个参数为摄像机的外参数(extrinsicparameter),可以理解为两个坐标原点之间的距离,因其受x,y,z三个方向上的分量共同控制,所以其具有三个自由度。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 4479

Redis快速入门:Key-Value存储系统简介

Redis是一个Key-Value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是

leo 5758

某Z节验证码

某Z节验证码、captchaBody、滑块、旋转、空间推理

mamenqi_csdn的博客 770

企业AI Agent的多模态学习在用户体验优化中的应用

本文旨在为企业技术团队提供关于多模态AI Agent在用户体验优化领域的全面技术指南。多模态学习如何突破传统单模态AI的局限性企业级AI Agent的系统架构设计原则多模态特征融合的工程实现细节用户体验度量的量化方法实际部署中的性能优化策略研究范围涵盖计算机视觉、自然语言处理、语音识别等多个AI子领域的技术融合,以及它们在电商、金融、医疗等行业的应用实践。首先介绍多模态学习的核心概念和技术原理然后深入分析关键算法和数学模型接着通过完整项目案例展示实际应用。

大模型应用工坊 706
上一篇: 大话Cassandra数据模型
下一篇: [译文]Cassandra实例
Java2King
博客等级 码龄18年 221粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值