27 Temmuz 2015 Pazartesi

Transactional Layer For Apache Cassandra

As all of you know, Apache Cassandra is the one of the most popular NoSQL databases. It is a time series database, succesful at scaling.

Last year in August, we were discussing swapping RDBMS database with a NoSQL database because RDBMS database can't scale enough for our customer requirements.

It is obvious that it is not that simple like swapping MySQL with Oracle (or vice versa) .You have to change a lot of things inside of your application.

The first thing , you have to change the data model.Besides you have to change transaction management of your application since there is no transactions in no sql (or there some lightweight transactions)

Hence, I have started to develop a transactional layer for Apache Cassandra.

I have to confess that transactions on NoSQL may not be adequate with NoSQL principles or it won't  resolve most of the problems while switching to NoSQL. It is an initial step to minimize the gap between enterprise world and NoSQL world.

It will be a simple layer;
  • Accepts CQL statements through a restful interface.
  • Keeps the transaction context again on the same cassandra database but in temporary tables.
  • Applies the changes after commit (or rollback)
 Let's start on a sample so I can explain the mechanism of cql-tx(name of transactional layer).

  • install cql-tx module
          npm install cql-tx 

  •  Go to cql-tx folder under node_modules folder update config.js file for logging path and cassandra configurations. (You may want to  change ports of rest and websocket interfaces)

var config = {
        restPort : 8080,
        websocketPort : 8081,
        trxClearanceIntervalInMins : 10,
        keyspace : 'mykeyspace',
        cassandraClient : {contactPoints: ['127.0.0.1'], keyspace: 'mykeyspace'},
        timezone : '+0300',
        winstonTransports : function(winston){
                            return [
                              new winston.transports.File({
                                  level: 'debug',
                                  filename: '/data/cqltx/logs/all-logs.log',
                                  handleExceptions: true,
                                  json: true,
                                  maxsize: 5242880, //5MB 
                                  maxFiles: 5,
                                  colorize: false
                              }),
                              new winston.transports.Console({
                                  level: 'debug',
                                  handleExceptions: true,
                                  json: false,
                                  colorize: true
                              })
                          ];
        }
}


  •  cql-tx uses some tables to keep transactions and table metadata so you need to execute init.js in order to create these metadata tables.
              node init.js

  •  You are ready to start cql-tx ;
              node start cql-tx

  • Now for a scenario , let's create a table called users;

        create table users(fname text,lname text,user_id bigint,primary key (user_id));
 
  • Open a transaction with the help of following curl command ;
curl -H "Content-Type: application/json" -X POST -d '{"commandType" : "openTransaction" }' http://localhost:8080/cqltx
  • Execute an insert statement with the help of following curl command (change the transaction id with the value that's returned by open-transaction) ;             
curl -H "Content-Type: application/json" -X POST -d '{"commandType" : "execute", "txId" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" ,"cql":"insert into users(user_id) values(64222)" }' http://localhost:8080/cqltx

  • At this point check  your users table, and check tx_users table;
              select * from users;
              select * from tx_users;

          You will see that your entry doesn't exist users while it exist on tx_users.
  • Commit the change (again change the transaction id);
curl -H "Content-Type: application/json" -X POST -d '{"commandType" : "commitTransaction", "txId" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" }' http://localhost:8080/cqltx

  • Again check your users table, and check tx_users table;
              select * from users;
              select * from tx_users;

          You will see that your entry doesn't exist tx_users while it exist on users. The change is commitied.
  • Before commit , if you want to rollback (again change the transaction id);
curl -H "Content-Type: application/json" -X POST -d '{"commandType" : "rollbackTransaction", "txId" : "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx" }' http://localhost:8080/cqltx
  • If a transaction is not finalized in time period (defined as trxClearanceInterval in config.js), it will be automatically rolled back. 

Java Driver for cql-tx

You can use cqltx-rest-driver for java platforms.It communicates with cql-tx over restful interface.(download)

Usage for users table:

CqlSessionFactory factory = new CqlSessionFactory(new URL("http://localhost:8080/cqltx"));
CqlSession session = factory.createNewSession();
session.execute("insert into users(user_id,fname,lname) values(44433,'test1','test2')");
session.commit();





cql-tx has many bugs and open points , I will be developing it. I am looking forward to your feedbacks....




Hiç yorum yok:

Yorum Gönder