Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Blazing Data with Redis (TrueNorthPHP)

Blazing Data with Redis (TrueNorthPHP)

There are many fast data stores, and then there is Redis. Learn about this excellent NoSQL solution that is a powerful in-memory key-value store. Learn how to solve traditionally difficult problems with Redis, and how you can benefit from 100,000 reads/writes a second on commodity hardware. We’ll discuss how and when to use the different datatypes and commands to fit your needs. We’ll discuss the different PHP libraries with their pros and cons. We’ll then show some live examples on how to use it for a chatroom, and how Redis manages a billion data points for our dating matching system. Finally, we’ll discuss some of the upcoming features in the near future, such as clustering and scripting.

Justin Carmony

December 30, 2013
Tweet

More Decks by Justin Carmony

Other Decks in Technology

Transcript

  1. About Me • Director of Development
 for DeseretNews.com • Utah

    PHP Usergroup
 President • I Make (and Break) 
 Web Stuff • Focus on Scalable, 
 Real-time Websites
 & APIs (I <3 Redis)
  2. About Presentation • We’ll ask for questions several times during

    presentation & the end. • I will post links, slides, resource, etc. • Goal: Educate & Inspire you on how, when, and
 why to use Redis!
  3. Real-Time Data • High Volume Writes • High Volume Reads

    • Low Latency / Delay • Grows Exponentially compared to Rest of your Data
  4. Traditional Data Stores • Examples: Databases (i.e. MySQL, Postgre) •

    Writing is Resource Intensive • Stored on Disk (aka Slower) • Slower as Volume Grows • Challenge for Replication (in other words...)
  5. Redis - Built for Speed • Key-Value Storage • In-Memory

    • Persistence • Multiple Data Types • Transactions • Pub/Sub w/ Blocking
 (and it’s Fast...)
  6. Redis is Awesome For: • Data with a high volume

    of Reads & Writes • Simple, Less-Relational Data Sets • Data that doesn’t have to be 100% durable • Data that can shard well.
  7. Step One:  Install & Run • Linux & Mac:

    Compile from Source • No Dependencies • make && make install • Windows • Download Binaries • Compile? Best of Luck
  8. Running Redis • Run: redis-server • Can use configuration file

    • Run as a “service”:
 http://redis.io/topics/ quickstart • redis-cli to try out commands

  9. Redis Keys • Keys MUST be UNIQUE • Keys are

    Binary Safe Strings • Super Long Keys (i.e. 1024 bytes) are costly to look up • Cryptic Short Keys (i.e. u:1000:pwd) have little performance improvement over a descriptive key (i.e. user:1000:password)
  10. This is not an RMDBS • It’s All About the

    Keys,
 Not the Values • There is no “querying” * • There are no “indexes” • There are no “schemas” * - not 100% true since redis 2.8.0, will cover why later
  11. Redis Strings • Store Simple Strings • Binary Safe •

    Great for JSON • Advanced Commands
  12. Quick Variable Guide • Hashes - Small in Size, Very

    Efficient • Lists - Awesome Queues, Size Doesn’t Affect Performance • Sets - Great for Intersecting with others • Sorted Sets - Use to Keep “Indexes”, Sorts using Scores
  13. Learning the Commands • Generic Commands for
 All Keys •

    Commands for Each
 Data Type • Each Command has 
 Big O Notation for 
 Performance • Simple, Yet Powerful
  14. Using Redis With PHP • Predis • PHP Library •

    Easy to Use • Very Fast to Update New Features • phpredis • PHP Extension • Faster, but requires
 compiling module We’ll Be Using
 Predis
  15. Simple Cache • Data Types: • Strings • Commands: •

    SETEX <key> <seconds to expire> <value> • GET <key> • EXPIREAT <key> <timestamp>
  16. Connecting <?php
 
 // Include the Predis Autoloader
 require 'predis/lib/Predis/Autoloader.php';


    
 // Register the Autoloader
 Predis\Autoloader::register();
 
 // Create a Client with defaults
 $redis = new Predis\Client();
 
 // Create with Connection String
 $redis = new Predis\Client('tcp://10.0.0.1:6379');
 " /** Our Examples Will Assume This Is Already Done **/
  17. Simple Cache $key = 'cache.user:justin';
 
 $data_str = $redis->get($key);
 


    if($data_str)
 {
 " $data = unserialize($data_str);
 }
 else
 {
 " // Really Expensive Method of Getting This Data
 " $data = MyDatabase::GetExpensiveData();
 " $redis->setex($key, 60, serialize($data));
 }
 
 /* Do something with the $data */
  18. Example: Online Users • Data Types: • Sets • Commands:

    • SADD <key> <value> • SUNION <key1> <key2> <key3> <key....> • EXPIRE <key> <timestamp>
  19. Marking Users Online /* Store Current User */
 // Current

    User ID
 $user_id = 1234;
 " // Get Current Time
 $now = time();
 $minute = date("i",$now);
 " // Generate the Key
 $key = "online:".$minute;
 " // Adding user to online users
 $redis->sadd($key, $user_id);
 $redis->expire($key, 60 * 10); // Expire in 10 minutes
  20. Getting Online Users /* Getting Onling Users */
 $keys =

    array();
 // Get Current Time
 $now = time();
 $minute = date("i",$now);
 
 $count = 0;
 $minutes_ago = 5;
 while($count < $minutes_ago)
 {
 " $keys[] = "online:".$minute;
 " 
 " $count++;
 " $min--;
 " if($min < 0)
 " {
 " " $min = 59;
 " }
 }
 // create command: SUNION online:10 online:9 online:8 online:7 online:6
 $scmd = $redis->createCommand("sunion",$keys);
 $online_ids = $redis->executeCommand($scmd);

  21. Example: Friends Online • Data Types: • Sets • Additional

    Commands: • SUNIONSTORE <dest> <key1> <key2> <key....> • SINTER <key1> <key2> <key...>
  22. My Friends Online /* My Friends Online */
 $keys =

    array('online_users');
 $user_id = '1234';
 // Get Current Time
 $minute = date("i",time());
 
 $count = 0;
 $minutes_ago = 5;
 while($count < $minutes_ago)
 {
 " $keys[] = "online:".$minute;
 " $count++;
 " $min--;
 " if($min < 0) { $min = 59; }
 }
 
 // SUNIONSTORE online_users online:10 online:9 online:8 online:7 online:6
 $scmd = $redis->createCommand("sunionstore",$keys);
 $redis->executeCommand($scmd);
 // SINTER online_users user_id:1234.friends_ids
 $online_friend_ids = $redis->sinter('online_users'
 " , 'user:'.$user_id.'.friend_ids');
  23. Few Things About Redis • Single Threaded • Can “Shard”

    For More Capacity / Performance • All Commands are Atomic • Transactions for Multiple Atomic Commands • Pipelining for High Performance
  24. Persistence • Snapshots on a Configurable Schedule • Will “fork”

    the process and write the DataSet to Disk • Append-Only File • Will Let You Survive a “Reboot”
  25. Lua Scripting • Introduced: Redis 2.6.0 • Allows for “querying”,

    more like Map/ Reduce • Great for common, reusable logic
  26. Pattern Scanning • In Redis 2.8.0 support was added for

    cursor-based scanning keys, hashes, sets, sorted sets, and lists.
  27. Redis Cluster • redis-cluster is currently being developed & a

    release candidate can be downloaded to try out. • Allows for master-master cluster • Right now only recommended for advanced users at the moment.
  28. Thanks! Rate My Talk (PLEASE): https://joind.in/6486 " Twitter: @JustinCarmony "

    IRC: carmony #uphpu #phpc #salt " Website: http://www.justincarmony.com/blog " Email: [email protected]
  29. Example: Chat Room • Data Types: Hashes, Sorted-Sets, Pub/Sub •

    Commands: • INCR <key> • HSET <key> <field> <val> • HMGET <key> <field1> <field2> <field...> • ZADD <key> <score> <member>