Cassandra Day - Application Development

来源:https://github.com/DataStax-Academy/cassandra-day-2019
介绍Cassandra实际的应用

展开查看详情

1. So u rc e Co de In s id e Cassandra Day Application Development 1 @DataStaxAcademy #CassandraDay

2. KillrVideo - a video sharing application 2 @DataStaxAcademy #CassandraDay

3. KillrVideo https://github.com/KillrVideo/killrvideo-java https://killrvideo.github.io https://github.com/KillrVideo 3 @DataStaxAcademy #CassandraDay

4. KillrVideo Architecture Your Browser Technology Choices Deployment Web • Node.js Application • Download and run locally • Falcor via Docker • Java / C# / Node.js / • Deployed in AWS using Python DataStax Managed KillrVideo • GRPC Services Cloud: • Etcd http://killrvideo.com/ • DataStax Drivers • DataStax Enterprise including Apache Cassandra & Spark, Graph 4 @DataStaxAcademy #CassandraDay

5. DataStax Drivers • OSS Cassandra Drivers • DataStax Enterprise Drivers – CQL Support – OSS Driver features plus... – Sync / Async API – Unified Authentication – Load Balancing – Graph Fluent API – Auto Node Discovery – Geometric Types – Object Mapper • ODBC • JDBC 5 @DataStaxAcademy #CassandraDay

6. Maven • Pom file (?) <dependency> <groupId>com.datastax.dse</groupId> <artifactId>dse-java-driver-core</artifactId> <version>1.7.0</version> </dependency> LINK 6 @DataStaxAcademy #CassandraDay

7. Connectivity OSS Driver DSE Driver Cluster.Builder DseCluster.Builder Build Build Cluster DseCluster connect connect Session DseSession 7 @DataStaxAcademy #CassandraDay

8.Builder ? 8 @DataStaxAcademy #CassandraDay

9.Builder DseCluster myCluster = DseCluster .builder() .addContactPoint("192.168.0.1") .build() 9 @DataStaxAcademy #CassandraDay

10. Contact Points Only one necessary Unless that node is down More are good Seed nodes are good; more “in the know” 10 @DataStaxAcademy #CassandraDay

11. Builder ! Builder Build Builder clusterbuilder = new Builder(); clusterbuilder.addContactPoint("192.168.0.1"); clusterbuilder.addContactPoint("192.168.0.2"); DseCluster clusterbuilder.addContactPoint("192.168.0.3"); clusterbuilder.withPort(9042); connect LINK DseSession 11 @DataStaxAcademy #CassandraDay

12. Load balancing new TokenAwarePolicy( new DCAwareRoundRobinPolicy("local-dc-name")) 12 @DataStaxAcademy #CassandraDay

13. Retry Policies • Most are deprecated (long story; don’t ask) • DefaultRetryPolicy – Default – Retries once onReadTimeout or onWriteTimeout – Enough replicas for your consistency level must be online – Only retries idempotent mutations • FallthroughRetryPolicy – Doesn’t retry – Sends exception to your client application 13 @DataStaxAcademy #CassandraDay

14. Reconnection Policies Reconnects driver to a downed node Two options: • ConstantReconnectionPolicy – Check every N milliseconds • ExponentialReconnectionPolicy (default) – Increases every interval – Caps out at a max 14 @DataStaxAcademy #CassandraDay

15. Builder !!!!!! Builder clusterbuilder = new Builder(); clusterbuilder.addContactPoint("192.168.0.1"); clusterbuilder.addContactPoint("192.168.0.2"); clusterbuilder.addContactPoint("192.168.0.3"); Builder clusterbuilder.withPort(9042); clusterbuilder.withReconnectionPolicy( Build new ExponentialReconnectionPolicy(1000, 1600)); clusterbuilder.withLoadBalancingPolicy( new TokenAwarePolicy( DseCluster DCAwareRoundRobinPolicy.builder() .withLocalDc("DC WEST").build())); connect clusterbuilder.withRetryPolicy( DefaultRetryPolicy.INSTANCE); clusterConfig.withAuthProvider( DseSession new DsePlainTextAuthProvider("Black", "Knight")); 15 @DataStaxAcademy #CassandraDay

16. connect DseCluster myCluster = clusterbuilder.build(); DseSession mySession = myCluster.connect("killrvideo"); Builder // DseSession mySession = myCluster.connect(); Build DseCluster connect DseSession LINK 16 @DataStaxAcademy #CassandraDay

17. DseSession is all you need ! DseCluster.Builder For when you need to do something quick and dirty Build DseCluster mySession.execute("SELECT * FROM users"); connect Statement LINK DseSession You know…sometimes you just got to get something done 17 @DataStaxAcademy #CassandraDay

18. SimpleStatement • Driver interprets SimpleStatements at runtime and may include parameter placeholders • You can set options on a SimpleStatement instance Statement statement = new SimpleStatement("select * from t1 where c1 = 5" ); Statement statement2 = new SimpleStatement("select * from t1 where c1 = ?", 5 ); mySession. execute(statement); 18 @DataStaxAcademy #CassandraDay

19. Prepared and Bound Statements • Compiled once on each node automatically as needed • Prepare each statement only once per application • Use one of the many bind variations to create a BoundStatement PreparedStatement ps = session.prepare("SELECT * from t1 where c1 = ?" ); BoundStatement bound = ps.bind(5); LINK 19 @DataStaxAcademy #CassandraDay

20. Query Builder 20 @DataStaxAcademy #CassandraDay

21. QueryBuilder • Alternative to building CQL string queries manually • Contains methods to build SELECT, UPDATE, INSERT and DELETE statements • Generates a Statement as per the earlier techniques Method Return Type QueryBuilder.select() Selection QueryBuilder.insertInto() Insert QueryBuilder.update() Update QueryBuilder.delete() Selection LINK 21 @DataStaxAcademy #CassandraDay

22. QueryBuilder QueryBuilder .update("killrvideo" , "video_ratings" ) .with(QueryBuilder.incr( "rating_counter" )) .and(QueryBuilder.incr( "rating_total" , QueryBuilder.bindMarker())) .where(QueryBuilder.eq( "videoid", QueryBuilder.bindMarker())) 22 @DataStaxAcademy #CassandraDay

23. execute() → ResultSet ResultSet rs = mySession. execute("SELECT * FROM users" ); // Gets all Rows (pages) at once List<Row> myRows = rs.all(); // Better - iterate! rs.forEach(row -> { System.out.println (row.getDouble( "ColX")); }); // Working with individual Rows Row singleRow = rs.one(); int col1 = singleRow.getInt( "c1"); String col2 = singleRow.getString( "c2"); 23 @DataStaxAcademy #CassandraDay

24. Exercise 24 @DataStaxAcademy #CassandraDay

25. Object Mapper • Map Java entity beans to CQL tables CREATE TABLE IF NOT EXISTS users ( userid uuid, firstname text, lastname text, email text, created_date timestamp, PRIMARY KEY (userid) ); 25 @DataStaxAcademy #CassandraDay

26. public class User { private UUID userid; private String firstname; private String lastname; private String email; private Date createdAt; public User() {} public User(UUID userid, String firstname, String lastname, String email, Date createdAt) { this.userid = userid; this.firstname = firstname; this.lastname = lastname; this.email = email; this.createdAt = createdAt; } // Getters and Setters public UUID getUserid() { return userid; } public void setUserid(UUID userid) { this.userid = userid; } } 26 @DataStaxAcademy #CassandraDay

27. @Table(keyspace = "killrvideo", name = "users") public class User { @PartitionKey private UUID userid; @Column @Length(min = 1, message = "firstName must not be empty") private String firstname; @Column @Length(min = 1, message = "lastName must not be empty") private String lastname; @Column @Length(min = 1, message = "email must not be empty") private String email; @NotNull @Column(name = "created_date") private Date createdAt; // Constructors // Getters and Setters } 27 @DataStaxAcademy #CassandraDay

28. Mapper // Execute Once MappingManager manager = new MappingManager(meSession); Mapper<User> userMapper = manager.mapper(User. class); // Usage Result<User> users = userMapper.map(meSession.execute(meQuery)); 28 @DataStaxAcademy #CassandraDay

29. Paging • Pulling large result sets all at once may not make sense • Retrieve sections or (pages) • Retrieve more…if necessary • Default of 5,000 @DataStaxAcademy #CassandraDay Paging 29