Lessons Learned: Handling ACID properties with Apache Cassandra

images

If you choose to use Apache Cassandra as your NoSQL database, keep in mind that you must consider the following characteristics in order to implement and design your model.

The Apache Cassandra is not fully compliance with ACID properties, however when design the application and the database model all of these properties and how Cassandra handle it should be considered.

See the following topics:

Isolation and Consistency

Apache Cassandra does not have isolation feature, so you must design considering that will not exist concurrency. It does not have lock feature comparing to relational databases, and so the approach must to be different. Consider the following scenario and how to handle it:

Many events arrive simultaneously to your system and you should parallelize to ensure performance. However, each event reads and write a same data that is stored in Cassandra, of course you should read the record and then write, however there is no isolation guarantee, and then it can share outdated data processing and thus may be inconsistent. The best way fix this scenario should be to get all the data you need and process it in memory and then update (write) in batch or serialized in order to evict chance of conflict.

Atomicity

One of the strongest features of the relational approach is atomicity that within a transactional context when an exception occurs all database updates are undone. It is the famous law of commit or rollback. However, Cassandra does not provide this transactional feature coupled with application method transaction and then the implementation of these scenarios turns complex. See the following situations and how to handle them:

# 1 – Within a application method that updates multiple tables in Cassandra it is necessary to ensure that all updates must be made in atomic way. In this scenario it is interesting to use batch feature that API provides and place within the same batch all writes of all tables.

# 2 – Within a application method you should ensure that others points may occurs errors (eg a REST call) and then the context should be rolled back. In this scenario it is interesting to create compensation routines: it should be an exception block to undo the update or create retentive routine to the point that has not been updated.

Asynchronous/Parallel Programming

One of the strongest features of Cassandra is the writing/reading optimization. However, the writing method used in the client can be more effective then using a serialized approach or even using batches. See the following scenario and how to handle it:

You will need to write to Cassandra a few million of records and the scenario implementation shoould be different ways:

# 1 – Write the records in the serialized way, it is one by one each of the records but this approach is not the most performative because its application should wait for execution confirmation.
# 2 – Write the records in the batch way, it is sending a block of records, but this way shoud increase network latency when handling very large block.

But we have a third approach that seems quite interesting, specially when not requiring transactional context: use the feature of parallel programming provided by the API. In the Java API, the driver handle the Future features (using Guava) and in our tests seemed much more performative than other approaches above. However, be careful because this feature uses threads and so your application must be set up to manage a large volume of threads.

Conclusion

The design and implementation of your application should use total different approach comparing when using a relational and transactional database. Keep in mind all of these characteristics should carefully be considered in design once we always used relational aproach.

See more:

http://docs.datastax.com/en/cassandra/2.0/cassandra/dml/dml_about_transactions_c.html 

Advertisements

Os segredos de escalabilidade da Spotify

Como o Spotify consegue entregar serviço de áudio com qualidade e performance. Pois bem, o “segredo” não é segredo para ninguém. Veja a provocação abaixo:

twitter

Como podem ver, a abordagem é bem antiga e funciona até hoje. Eu vou tentar sintetizar aqui o que ví na #devcamp2015. A apresentação é do Niklas Gustavsson (@protocol7), Lead Engineer da Spotify.

Basicamente, são 3 grandes pontos a serem destacados na abordagem utilizada pelo Spotify:

  1. Arquitetura orientada a serviços: microserviços
  2. Técnicas para Content Delivery
  3. Tecnologias “quentes”

Agora, vamos detalhar cada um destes pontos:

1. Arquitetura orientada a serviços: microserviços

spotify

Sim, microserviços é um dos “segredos” do Spotify! Basicamente ao dar responsabilidades bem definidas para os componentes, eles conseguem escalar cada um desses componentes ou mesmo evoluir com menos impacto cada um deles. Vou explicar um pouco da responsabilidade de cada um:

– Access Point Services: serviços que roteiam para outros serviços com responsabilidade de orquestrar e agregar outros serviços. Porta de entrada inicial com responsabilidades sobre questões cruciais como segurança e load balancing.

– View Services: serviços que “preparam” os dados para a camada de visão ou seja, deixam os dados mais preparados para serem facilmente consumidos por seus clientes. E.g mobile app e site.

– Data Services: Serviços de dados com responsabilidades de leitura e escrita

– Meta Data Services: Serviços que “dão” sentido aos dados “crus” dos data services. Geram dados canônicos, composição / agregação de dados, etc.

2. Técnicas para entrega de conteúdo

Content Delivery é uma tarefa simples não ? Temos muitas soluções de mercado, certo ? Pois bem, a tarefa não é tão simples quando se fala em streaming, bem como tais soluções de mercados não funcionam tão bem como prometem. Vejamos o que eles fazem sobre este assunto.

– Latência importa!!! Sim, importa e muito, pois seu cliente quer abrir o aplicativo e começar a escutar a musica sem esperar e sem interrupções, e nesse sentido quanto mais próximo do cliente melhor, a latência diminui e conteúdo é entregue mais rápido. Neste sentido, o Spotify sempre está atento aos serviços que hospedam mais próximos dos seus consumidores.

– CDN ajuda! Arquivos estáticos como imagens são armazenadas nos CDN’s garantem alta disponibilidade e baixa latência para os arquivos mais populares,

– Streaming começa com download de arquivo. Pois é, você pensou que ao iniciar uma musica, você já estava em live streaming, certo ? Não é bem assim, o pulo do gato é download de um arquivo pequeno de inicialização com o trecho inicial da música chamado “Headfile”

3. Tecnologias “quentes”

Quando se fala em tecnologias “quentes” pensamos em algo inovar e muito distante, correto ? Basicamente o que o Spotify usa é Java!! Tanto que até um de seus principais banco de dados é em Java, o Cassandra, desta forma vamos falar um pouco do Cassandra e de Java.

– A escolha do Cassandra: características como alta disponibilidade, multi-site por região, facilidades de replicação dados entre regiões fazem muito sentido para eles. Outro ponto favorável é a performance de streams de dados que vem continuamente do cliente para escrita com muita performance bem como recuperação de dados por views.

– Aproveitando as novas features de Java 7/8: Uso intensa de API de Streams, Lambdas e API Futures são fundamentais.

Ainda, faço um adendo aqui sobre uma característica que acho fundamental para aplicações escalarem e ter performance: Uso e abuso de assincronismo e paralelismo! Chega de economizar e blockar threads!

E por fim, termino com uma frase irônica do Niklas sobre o Java. Vale lembrar que ele é pythonista!

Java is a shit language in an awesome VM while Python is a awesome language in a shit VM