【Golang】初次使用Cassandra数据库
总结
由于我在Golang中将Cassandra用作会话管理的数据库,因此我将其撰写成了一篇文章。Cassandra可以通过在多台服务器上构建集群来创建分布式数据库并进行横向扩展,因此可以轻松实现可扩展性。此外,处理性能与节点数量的配置成比例。因此,作为服务器管理员,您可以相对低廉地保证可伸缩性。
Cassandra是一种可以将数据存储在表中,并且可以使用类似于SQL的查询语言CQL进行数据交互的数据库。因此,通过直观操作,几乎可以像使用关系型数据库一样进行操作。以前,我也在【Golang】mysql数据库处理的文章中介绍了使用SQL库进行Golang处理的方法,对于Cassandra数据库,使用CQL将会有类似的处理方式。
※我是在Mac环境下进行的。
※请参考《第一次使用Golang构建Web应用程序至测试、Docker容器化的基本设置和用法》来学习Golang的基本设置和用法。
Cassandra的基本内容(安装、数据库和表的创建)
请使用以下命令进行安装。
brew install cassandra
sudo pip install cql
使用以下命令创建了名为oauth的数据库和名为access_token的表。
describe keyspaces;
>system_traces system_schema system_auth system system_distributed
CREATE KEYSPACE oauth WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':1};
describe keyspaces;
>system_schema system_auth system system_distributed oauth system_traces
USE oauth;
CREATE TABLE access_tokens( access_token varchar PRIMARY KEY, user_id bigint, expires bigint);
describe tables;
>access_tokens
SELECT * from access_tokens where access_token='doNaDonaEtc';
access_token | expires | user_id
--------------+---------+---------
安装 Golang gocql 包
安装gocql包。
go get github.com/gocql/gocq
在本文中的操作示例
在本文中,我们将提供有关处理的示例,如下所示。此外,我们还提供了执行此处理的程序,如下所示。
-
- 创建一个名为access_token的数据。
-
- 向dbRepo注入CassandraDB的接口(数据库处理的包已分离)
-
- 使用Create方法插入数据
- 使用Get方法获取数据
※accessToken 是一个包含了 access_token 结构体和相关处理的包。由于与本文的流程无关,故在此省略说明。
package main
import (
"fmt"
access_token "github.com/k-washi/golang-cookbook/cassandraDB/c1/c1/accessToken"
"github.com/k-washi/golang-cookbook/cassandraDB/c1/c1/oauthdomain"
)
func main() {
at := access_token.GetAccessToken()
at.AccessToken = "doNaDonaEtc"
at.UserID = 123
dbRepo := oauthdomain.NewRepo()
err := dbRepo.Create(at)
if err != nil {
fmt.Println(err)
}
accessToken, err := dbRepo.GetID(at.AccessToken)
if err != nil {
fmt.Println(err)
}
fmt.Println(accessToken) //&{doNaDonaEtc 123 1580498041}
/*
cqlsh:oauth> SELECT * from access_tokens where access_token='doNaDonaEtc';
access_token | expires | user_id
--------------+------------+---------
doNaDonaEtc | 1580498041 | 123
*/
}
卡桑德拉的配置
展示一个用Golang编写的配置Cassandra的程序。使用GetSession()获取Session,在数据库的每个方法中用于连接。
package cassandra
import (
"fmt"
"github.com/gocql/gocql"
)
var (
session *gocql.Session
)
func init() {
// connect to Cassandra
cluster := gocql.NewCluster("127.0.0.1")
cluster.Keyspace = "oauth"
cluster.Consistency = gocql.Quorum
var err error
if session, err = cluster.CreateSession(); err != nil {
panic(err)
}
fmt.Println("cassandra config success")
}
func GetSession() *gocql.Session {
return session
}
卡桑德拉数据库的方法 (Kǎ dé lā shù jù kù de fǎ)
我們在此實施了GET、CREATE和UPDATE方法。作為查詢,我們使用了類似於SQL的CQL。我們接收Cassandra的設定,然後將查詢發送給它並接收結果。
package oauthdomain
import (
"errors"
access_token "github.com/k-washi/golang-cookbook/cassandraDB/c1/c1/accessToken"
"github.com/gocql/gocql"
"github.com/k-washi/golang-cookbook/cassandraDB/c1/c1/cassandra"
)
const (
queryGetAcessToken = "SELECT access_token, user_id, expires FROM access_tokens WHERE access_token=?;"
queryCreateAccessToken = "INSERT INTO access_tokens(access_token, user_id, expires) VALUES (?, ?, ?);"
queryUpdateExpires = "UPDATE access_tokens SET expires=? WHERE access_token=?;"
)
func NewRepo() DbRepo {
return &dbRepo{}
}
type DbRepo interface {
GetID(string) (*access_token.AccessToken, error)
Create(access_token.AccessToken) error
UpdateExpirationTime(access_token.AccessToken) error
}
type dbRepo struct{}
func (r *dbRepo) GetID(at string) (*access_token.AccessToken, error) {
session := cassandra.GetSession()
var result access_token.AccessToken
if err := session.Query(queryGetAcessToken, at).Scan(
&result.AccessToken,
&result.UserID,
&result.Expires,
); err != nil {
if err == gocql.ErrNotFound {
return nil, errors.New("no access token found with given id")
}
return nil, err
}
return &result, nil
}
func (r *dbRepo) Create(at access_token.AccessToken) error {
session := cassandra.GetSession()
if err := session.Query(queryCreateAccessToken,
at.AccessToken,
at.UserID,
at.Expires,
).Exec(); err != nil {
return err
}
return nil
}
func (r *dbRepo) UpdateExpirationTime(at access_token.AccessToken) error {
session := cassandra.GetSession()
if err := session.Query(queryUpdateExpires,
at.Expires,
at.AccessToken,
).Exec(); err != nil {
return err
}
return nil
}