- CDH 5 Release Notes
- CDH 5 Requirements and Supported Versions
- CDH 5 Quick Start Guide
- CDH 5 Installation Guide
- What's New in CDH 5
- Before You Install CDH 5 on a Cluster
- CDH 5 and MapReduce
- CDH 5 Installation
- Migrating from MapReduce v1 (MRv1) to MapReduce v2 (MRv2, YARN)
- Upgrading to CDH 5 from CDH 4
- Upgrading from a CDH 5 Beta Release to the Latest Version
- Migrating data between a CDH 4 and CDH 5 cluster
- Configuring Ports for CDH 5
- Deploying CDH 5 in Pseudo-Distributed Mode
- Deploying CDH 5 on a Cluster
- About HDFS Snapshots
- Crunch Installation
- Flume Installation
- Upgrading Flume
- Flume Packaging
- Installing the Flume Tarball
- Installing the Flume RPM or Debian Packages
- Flume Configuration
- Verifying the Installation
- Running Flume
- Files Installed by the Flume RPM and Debian Packages
- Supported Sources, Sinks, and Channels
- Using an On-disk Encrypted File Channel
- Viewing the Flume Documentation
- HBase Installation
- Upgrading HBase
- Installing HBase
- Configuration Settings for HBase
- Starting HBase in Standalone Mode
- Configuring HBase in Pseudo-Distributed Mode
- Deploying HBase on a Cluster
- Accessing HBase by using the HBase Shell
- Using MapReduce with HBase
- Troubleshooting
- Viewing the HBase Documentation
- HBase Replication
- Configuring HBase Snapshots
- Installing and Using HCatalog
- HCatalog Prerequisites
- Installing and Upgrading the HCatalog RPM or Debian Packages
- Configuration Change on Hosts Used with HCatalog
- Starting and Stopping the WebHCat REST server
- Accessing Table Information with the HCatalog Command-line API
- Accessing Table Data with MapReduce
- Accessing Table Data with Pig
- Accessing Table Information with REST
- Viewing the HCatalog Documentation
- Impala Installation
- Hive Installation
- About Hive
- Upgrading Hive
- Installing Hive
- Configuring the Hive Metastore
- Configuring HiveServer2
- Starting the Metastore
- File System Permissions
- Starting, Stopping, and Using HiveServer2
- Using Hive with HBase
- Using the Hive Schema Tool
- Installing the Hive JDBC on Clients
- Setting HADOOP_MAPRED_HOME
- Configuring the Metastore to use HDFS High Availability
- Troubleshooting
- Viewing the Hive Documentation
- HttpFS Installation
- Hue Installation
- Llama Installation
- Mahout Installation
- Oozie Installation
- Pig Installation
- Search Installation
- Sentry Installation
- Snappy Installation
- Spark Installation
- Sqoop Installation
- Sqoop 2 Installation
- Whirr Installation
- ZooKeeper Installation
- Avro Usage
- Using the Parquet File Format with Impala, Hive, Pig, and MapReduce
- Maintenance Tasks and Notes
- Mountable HDFS
- Configuring an NFSv3 Gateway
- Java Development Kit Installation
- Creating a Local Yum Repository
- Using the CDH 5 Maven Repository
- Building RPMs from CDH Source RPMs
- Getting Support
- Apache and Third-Party Licenses
- CDH Version and Packaging Information
- CDH 5 Security Guide
- Introduction to Hadoop Security
- Configuring Hadoop Security in CDH 5
- Step 1: Install CDH 5
- Step 2: Verify User Accounts and Groups in CDH 5 Due to Security
- Step 3: If you are Using AES-256 Encryption, install the JCE Policy File
- Step 4: Create and Deploy the Kerberos Principals and Keytab Files
- Step 5: Shut Down the Cluster
- Step 6: Enable Hadoop Security
- Step 7: Configure Secure HDFS
- Optional Step 8: Configuring Security for HDFS High Availability
- Optional Step 9: Configure secure WebHDFS
- Optional Step 10: Configuring a secure HDFS NFS Gateway
- Step 11: Set Variables for Secure DataNodes
- Step 12: Start up the NameNode
- Step 12: Start up a DataNode
- Step 14: Set the Sticky Bit on HDFS Directories
- Step 15: Start up the Secondary NameNode (if used)
- Step 16: Configure Either MRv1 Security or YARN Security
- Configuring MRv1 Security
- Configuring YARN Security
- Configuring Sentry
- Flume Security Configuration
- Hue Security Configuration
- Oozie Security Configuration
- HttpFS Security Configuration
- HBase Security Configuration
- Impala Security Configuration
- Hive Security Configuration
- HCatalog Security Configuration
- ZooKeeper Security Configuration
- Search Security Configuration
- FUSE - Mountable HDFS Security Configuration
- Sqoop, Pig, and Whirr Security Support Status
- Configuring Encrypted Shuffle, Encrypted Web UIs, and Encrypted HDFS Transport
- Integrating Hadoop Security with Active Directory
- Integrating Hadoop Security with Alternate Authentication
- Appendix A – Troubleshooting
- Appendix B - Information about Other Hadoop Security Programs
- Appendix C - Configuring the Mapping from Kerberos Principals to Short Names
- Appendix D - Enabling Debugging Output for the Sun Kerberos Classes
- Appendix E - Task-controller and Container-executor Error Codes
- Appendix F - Using kadmin to Create Kerberos Keytab Files
- Appendix G - Setting Up a Gateway Node to Restrict Access
- Appendix H - Configuring LDAP Group Mappings
- CDH 5 High Availability Guide
- Cloudera Impala User Guide
-
Using Cloudera Impala
- Impala Concepts and Architecture
- Impala Tutorial
- Impala Administration
- Impala SQL Language Reference
- Using the Impala Shell
- Tuning Impala for Performance
- Partitioning
- How Impala Works with Hadoop File Formats
- Using Impala to Query HBase Tables
- Using Impala Logging
- Appendix A - Ports Used by Impala
- Appendix B - Troubleshooting Impala
- Appendix C - Impala Reserved Words
- Cloudera Impala Frequently Asked Questions
-
Using Cloudera Impala
- CDH 5 Search Guide
- Cloudera Search User Guide
- Introducing Cloudera Search
- Understanding Cloudera Search
- Cloudera Search Tutorial
- Solrctl Reference
- MapReduce Batch Indexing Reference
- Flume Near Real-Time Indexing Reference
- Extracting, Transforming, and Loading Data With Cloudera Morphlines
- Using the Lily HBase Batch Indexer for Indexing
- Configuring Lily HBase NRT Indexer Service for Use with Cloudera Search
- High Availability and Fault Tolerance
- Tuning the Solr Server
- Troubleshooting Cloudera Search
- Cloudera Search Glossary
- Cloudera Search Frequently Asked Questions
- Cloudera Search User Guide
Tuesday, April 8, 2014
Impala docs now included in CDH 5 library
With the release of CDH 5.0.0 and Impala 1.3.0, now for the first time the Impala docs are embedded alongside the CDH Installation Guide, Security Guide, and other CDH docs. This integration makes it easier to link back and forth both ways, and also will help readers find Impala-related content when they search within the CDH 5 library.
Here's the full layout of the CDH 5.0.0 library. Notice that the primary "using" information for Impala is grouped together near the end. Release notes, install / upgrade / config, and security topics are integrated next to the related information for other CDH components.
Thursday, February 6, 2014
Impala Doc Reorg - January 2014
When Impala started, many of the early adopters were experts in HiveQL, so the Impala documentation assumed some familiarity with Hive SQL syntax and behavior. The Impala SQL reference info was relatively low-volume, more of a quick reference.
Now there's more functionality to talk about, and more users are starting with Impala straight from an RDBMS background and need the full details from the ground up. So the Impala docs are reorganized a little, to set the stage for further expansion. No pages are going away, so you won't get any 404 errors. Large pages (particularly in the SQL reference and Security areas) are being split up, making the navigation tree in the left sidebar more useful for jumping between related subtopics.
Here's the current layout, with bold indicating topics that were recently split out into their own separate pages:
- Cloudera Impala Release Notes
-
Installing and Using Cloudera Impala
- Impala Concepts and Architecture
- Installing Impala
- Configuring Impala
- Upgrading Impala
- Starting Impala
- Impala Tutorial
- Administering Impala / Impala Administration
- Impala Security
- Impala SQL Language Reference
- Using the Impala Shell
- Tuning Impala for Performance
- Partitioning
- How Impala Works with Hadoop File Formats
- Using Impala to Query HBase Tables
- Using Impala Logging
- Appendix A - Ports Used by Impala
- Appendix B - Troubleshooting Impala
- Appendix C - Impala Reserved Words
- Cloudera Impala Version and Download Information
- Cloudera Impala Frequently Asked Questions
Saturday, December 7, 2013
My history with Big Data
Before I joined Cloudera, I hadn't had much formal experience with Big Data. But I had crossed paths with one of its major use cases before, so I found it easy to pick up the mindset.
My previous big project involved a relational database hooked up to a web server. Naturally I wanted to be able to track visitor stats, detect denial-of-service attacks, and chart the most popular pages, search terms, referrers, etc. Since I had more control over the database side, I threw all the relevant fields from the HTTP header and query string into a database table, all divided nicely into columns. With SQL queries, problems were easy to detect, trends were easy to spot, questions were easy to answer. Life was good.
As the system grew, the logging table grew to a point where it hit a bottleneck due to defaults set up years before. A simple single-row INSERT statement into this logging table could stall for minutes at a time. There was a more scalable layout for the table (IIUC, this feature didn't exist when my application was first deployed), but the combination of constant traffic on the site plus relatively little spare space to reorganize things meant that the switchover had to be done in tiny increments, over a period of a couple of weeks.
I looked at the size of the table: a few tens of millions of rows, no more than 16GB total. I would shuffle more data than that around my hard drive after one day of shooting photos on vacation. Why couldn't I have a simple append-only data store without the relational and transactional overhead? But still with the nice SQL query interface, that was so convenient.
As time went by, the volume of log data came up again and again as a sticking point -- even though it was still miniscule by the standards of any computer hobbyist. The mechanism for looking at this info changed from querying a relational database to analyzing the raw Apache logs through Java code. Now there was an ETL process for getting each day's worth of data. It took long enough to transfer the files, then uncompress and analyze them, that now it was a race to finish before it was time to start on the next day's data. There wasn't space to keep around all the raw data files, so only summary information was kept permanently. Now, doing any new kind of analysis involved writing a custom Java program, and the analysis could only apply to a limited time period.
Given the tradeoffs, I preferred the original way of doing things, with a SQL interface to the data covering all time, even if meant more overhead on the recording side and periodic pleas for more storage space. I know Java, Java is on my resume, but I didn't think it made sense to write elaborate Java programs with classes and loops for what was a perfect use case for SQL 1-liners (or failing that, a scripting job for Python or Perl). What do you know, Hadoop is going through exactly the same maturation, with people concluding that Java-based MapReduce jobs aren't the most effective use of developer or computer time for queries that are in SQL's sweet spot.
This is why I am so keen on the dynamics of Hadoop and Big Data, especially as exemplified by Cloudera Impala. I know there is an army of people out there who know SQL, who have been held back all these years by having to plead for even modest amounts of storage space, and spent much of their time twiddling their thumbs waiting for some lengthy ETL process to finish. Give 'em some gigabytes, terabytes, or even petabytes of storage to work with; give 'em read access to the original data files without needless copying and conversion steps. And let the insights roll in.
Tuesday, May 14, 2013
Documentation for Cloudera Impala 1.0.1
The Cloudera docs have been undergoing some reorganization lately. That applies double to the Impala documentation, which moved from beta to GA status and has been restructured at the same time. The June 1.0.1 release brings some new reference information, so I've broken out the SQL language links too. For posterity (and a little Googlerank mojo), here's the current layout of the Impala docs in mid-June 2013:
- Cloudera Impala Release Notes
-
Installing and Using Cloudera Impala
- Impala Concepts and Architecture
- Installing Cloudera Impala
- Configuring Impala
- Upgrading Impala
- Impala Security with Kerberos Authentication
- Starting Impala
- Impala Tutorial
- Impala SQL Language Reference
- Impala SQL Language Elements
- ALTER TABLE
- AVG Function
- BIGINT
- BOOLEAN Data Type
- Comments
- COUNT Function
- CREATE DATABASE
- CREATE TABLE
- DESCRIBE
- DISTINCT Operator
- DOUBLE Data Type
- DROP DATABASE
- DROP TABLE
- EXPLAIN
- External Tables
- FLOAT Data Type
- GROUP BY Clause
- Hints
- INSERT
- INT Data Type
- Internal Tables
- Joins
- LIMIT Clause
- MAX Function
- MIN Function
- NULL
- ORDER BY Clause
- Partitioning
- REFRESH
- SELECT
- SHOW
- SMALLINT Data Type
- STRING Data Type
- SUM Function
- TIMESTAMP Data Type
- TINYINT Data Type
- USE
- VALUES Clause
- Unsupported Language Elements
- Built-in Function Support
- Impala SQL Language Elements
- Using the Impala Shell
- Tuning Impala Performance
- Understanding File Formats
- Using Impala to Query HBase Tables
- Using Impala Logging
- Appendix A - Ports Used by Impala
- Appendix B - Troubleshooting Impala
- Cloudera Impala Frequently Asked Questions
Monday, May 6, 2013
New Job for John
Hello readers of my infrequent blog posts! I have started a new job, working on documentation for Cloudera, specifically for the Impala project, which is bringing fast interactive SQL to the Hadoop ecosystem. Read the Impala documentation. Download the Impala software. Get the QuickStart VM to play around with a pre-installed system. (You'll need to start Impala from within the Cloudera Manager interface after booting the VM.)
Monday, December 10, 2012
Error Handling: Or, How to Start an Argument Among Programmers
Lately I see a lot of discussions come up about error handling. For example: Dr. Dobbs "The Scourge of Error Handling" covering mainly C-descended languages; this blog post stemming from OTN discussions of Oracle exception handling in PL/SQL. I've been on both sides of the fence (cowboy coder and database programmer) so I'll offer my take. I'll write mostly from the perspective of PL/SQL stored procedures, because that's where I've coded the biggest variety of error handlers. The same opinions apply to my programming in Python, Javascript, Java, or C++, that's just a lower volume of code.
I have a lot of sympathy for the Dr. Dobbs article's position that we've neglected error codes too much. I also don't mind PL/SQL's WHEN OTHERS clause as much as some people do.
It's true that exception handling is often used as a kludge that winds up simulating GOTOs and producing spaghetti code. In fact, I don't think I've ever seen a substantial body of code that used "admirable" exception-handling practices. People know some but not all of the things that could throw exceptions, so their try/catch blocks are insufficient. If you really want to protect and debug every operation that could throw an error, you need way more exception handling than anyone does in practice. (In theory, you could get some sort of out of memory, memory corrupted, or disk full error at any random time.) If you wind up maintaining someone else's code, basically any new bug is going to highlight the need for more granular exception handling, or dealing with some never-before-seen condition, or better recovery code in the caller.
For example, I was the author of the Oracle PL/SQL User's Guide for a time, and wrote more than 100K lines of PL/SQL code. I had many first-time encounters with hard-to-debug exceptions in purely PL/SQL operations, for things like nonexistent collection items, index out of range, bad datatype conversions, and so on. Those were often in query-intensive pieces of code where there was no need for a rollback, just an error message for a user or a slightly less-than-optimal query result for a search engine result page. The structure of stored procedures dealing with collection types often required putting separate try/catch blocks around every reference to an index variable, or constructing some debugging metadata using extra variables designating how far the routine had gotten. That didn't feel right; once the language leads you down a path that seems clunky, coders are less likely to stick to best practices in all other areas.
I also dealt with built-in PL/SQL stored procedures where I didn't know in advance what exceptions could be raised, and so learned over time what were the most likely ones to come back based on my imperfect understanding of the internal workings of some package. But how could I ever predict in advance all the things that could go wrong when settings were changed, the database upgraded, or some hardware limit was reached that I couldn't anticipate in a test environment? The people writing such routines, who have greater expertise with the internal operations, can just RAISE any exceptions and put the burden of predicting and handling them on you, the ill-informed caller. That feels like the wrong way round.
For those reasons, I wouldn't demand that WHEN OTHERS always propagate an exception back to the caller. It could be protecting a purely optional section of code, for example one that logs error conditions. (Which is already likely to be called when things are messed up in unexpected ways.) Or that produces some optional UI adornment that can be skipped in the name of keeping things running in the face of moderate problems. Personally, I'm happy when PL/SQL stored procedures tackle some new problem domain where not every code path is mission critical or represents a DML operation inside a transaction.
As a developer, you also don't necessarily get to control how unhandled exceptions are displayed or logged all the way back at the web layer. For example, the PL/SQL web gateway by default shows a stack trace, which makes unhandled exceptions easy to debug in a development/test environment. But that might be turned into a generic 404-style error page on the production web server, meaning it's just as well to handle the exception entirely yourself (WHEN OTHERS with no RAISE) and put up your own error page or make subtle changes to your page of search engine results or whatever.
The best argument I've seen against WHEN OTHERS THEN <something besides raise> is that the system could be so hosed that another exception occurs doing something you thought was completely innocuous inside the handler, leading to an infinite loop of exceptions. I've never encountered that myself, so I can't say how that works in practice.
Getting away from PL/SQL for a second...
In Javascript, you're almost always dealing with non-critical code paths. Which makes it more practical to do less granular error handling. (If errors X, Y, or Z occur during this function, don't display the ad widget we were trying to retrieve.)
Python's nice robust standard library and introspection makes it very pleasant to write exception handlers for routines you didn't write yourself. There are plenty of things you can do with scripting languages where, if you run out of memory or out of disk space, you can live with a sudden halt and an error report rather than extensive recovery actions. So in Python (and Perl, et. al.) I don't mind having a top-level exception handler and not going overboard with try/catch blocks for every operation that could fail.
I have a lot of sympathy for the Dr. Dobbs article's position that we've neglected error codes too much. I also don't mind PL/SQL's WHEN OTHERS clause as much as some people do.
It's true that exception handling is often used as a kludge that winds up simulating GOTOs and producing spaghetti code. In fact, I don't think I've ever seen a substantial body of code that used "admirable" exception-handling practices. People know some but not all of the things that could throw exceptions, so their try/catch blocks are insufficient. If you really want to protect and debug every operation that could throw an error, you need way more exception handling than anyone does in practice. (In theory, you could get some sort of out of memory, memory corrupted, or disk full error at any random time.) If you wind up maintaining someone else's code, basically any new bug is going to highlight the need for more granular exception handling, or dealing with some never-before-seen condition, or better recovery code in the caller.
For example, I was the author of the Oracle PL/SQL User's Guide for a time, and wrote more than 100K lines of PL/SQL code. I had many first-time encounters with hard-to-debug exceptions in purely PL/SQL operations, for things like nonexistent collection items, index out of range, bad datatype conversions, and so on. Those were often in query-intensive pieces of code where there was no need for a rollback, just an error message for a user or a slightly less-than-optimal query result for a search engine result page. The structure of stored procedures dealing with collection types often required putting separate try/catch blocks around every reference to an index variable, or constructing some debugging metadata using extra variables designating how far the routine had gotten. That didn't feel right; once the language leads you down a path that seems clunky, coders are less likely to stick to best practices in all other areas.
I also dealt with built-in PL/SQL stored procedures where I didn't know in advance what exceptions could be raised, and so learned over time what were the most likely ones to come back based on my imperfect understanding of the internal workings of some package. But how could I ever predict in advance all the things that could go wrong when settings were changed, the database upgraded, or some hardware limit was reached that I couldn't anticipate in a test environment? The people writing such routines, who have greater expertise with the internal operations, can just RAISE any exceptions and put the burden of predicting and handling them on you, the ill-informed caller. That feels like the wrong way round.
For those reasons, I wouldn't demand that WHEN OTHERS always propagate an exception back to the caller. It could be protecting a purely optional section of code, for example one that logs error conditions. (Which is already likely to be called when things are messed up in unexpected ways.) Or that produces some optional UI adornment that can be skipped in the name of keeping things running in the face of moderate problems. Personally, I'm happy when PL/SQL stored procedures tackle some new problem domain where not every code path is mission critical or represents a DML operation inside a transaction.
As a developer, you also don't necessarily get to control how unhandled exceptions are displayed or logged all the way back at the web layer. For example, the PL/SQL web gateway by default shows a stack trace, which makes unhandled exceptions easy to debug in a development/test environment. But that might be turned into a generic 404-style error page on the production web server, meaning it's just as well to handle the exception entirely yourself (WHEN OTHERS with no RAISE) and put up your own error page or make subtle changes to your page of search engine results or whatever.
The best argument I've seen against WHEN OTHERS THEN <something besides raise> is that the system could be so hosed that another exception occurs doing something you thought was completely innocuous inside the handler, leading to an infinite loop of exceptions. I've never encountered that myself, so I can't say how that works in practice.
Getting away from PL/SQL for a second...
In Javascript, you're almost always dealing with non-critical code paths. Which makes it more practical to do less granular error handling. (If errors X, Y, or Z occur during this function, don't display the ad widget we were trying to retrieve.)
Python's nice robust standard library and introspection makes it very pleasant to write exception handlers for routines you didn't write yourself. There are plenty of things you can do with scripting languages where, if you run out of memory or out of disk space, you can live with a sudden halt and an error report rather than extensive recovery actions. So in Python (and Perl, et. al.) I don't mind having a top-level exception handler and not going overboard with try/catch blocks for every operation that could fail.
Wednesday, August 29, 2012
Separate docs for MySQL Connectors
The MySQL documentation section has always had this Topic Guides page containing links to the docs for the various MySQL Connectors -- the official database drivers for various languages and programming technologies. That is the most convenient way to get the information for each Connector in PDF form, rather than downloading the entire Ref Man PDF. For HTML, it was more of a shortcut, because most HTML links led back into the Ref Man, where the Connectors material is embedded all in one chapter. (For example, "22.3. MySQL Connector/J".)
Now we have started building each of the Connectors sections as its own HTML doc, linked from the Topic Guides page. That allows for faster turnaround for updates -- sometimes the Ref Man takes a few days to be rebuilt and posted. Also, it gives each Connector its own TOC, making the the topics more visible than when they're pushed down several levels in the Ref Man. (For example, "22.3.7. Connection Pooling with Connector/J" becomes "Chapter 7. Connection Pooling with Connector/J".)
The language-themed Connectors are:
Now we have started building each of the Connectors sections as its own HTML doc, linked from the Topic Guides page. That allows for faster turnaround for updates -- sometimes the Ref Man takes a few days to be rebuilt and posted. Also, it gives each Connector its own TOC, making the the topics more visible than when they're pushed down several levels in the Ref Man. (For example, "22.3.7. Connection Pooling with Connector/J" becomes "Chapter 7. Connection Pooling with Connector/J".)
The language-themed Connectors are:
MySQL Connector/J for applications written in Java to the JDBC spec.
MySQL Connector/Net for applications written in C# and other .NET languages.
MySQL Connector/Python for applications written in Python. This one is new: an alternative to the MySQLdb module, currently in beta.
MySQL Connector/C++ for applications written in C++.
MySQL Connector/C for applications written in C.
MySQL Connector/ODBC for applications written to the ODBC spec.
Thursday, April 1, 2010
Wednesday, March 10, 2010
More on Single-Action UIs
In my post Deconstructing the iPod Shuffle UI, I talked a bit about the notion of a limited UI where you really only do one thing -- in that case, click the button on the headphones.
Every now and then, I rediscover the infrared remote that goes with my iMac, and realize that for many mundane tasks, the remote does everything I need. (Mira lets me assign different actions for the remote button for specific applications. Candelair works around a Snow Leopard issue with Mira.)
For example, with a new album in a photo library, you might want to Next-Next-Next through each photo, and if one is particularly bad, trash it; if one is particularly good, mark it with a high rank or a coloured label; otherwise, leave it as-is and proceed to the next one. The up/down/left/right/play buttons on the remote can accomodate those actions comfortably. All the photo software offers keyboard shortcuts for these actions, that can be assigned to the remote buttons. So this brain-intensive task can be accomplished while sitting back and taking in the view on a large screen.
One thing had been bothering me about the UI for the iPod Touch. If I'm listening to music with the screen turned off, say in the car or the office, and I'm interrupted (want to stop the music suddenly) or annoyed (want to immediately skip to the next song), normally this requires turning on the screen (Home button or power button), and unlocking the iPod by swiping before the music controls are available. I should have realized Apple would bring the "single-action UI" to the rescue. Instead of unlocking the whole unit, once it is powered on in a locked state, 2 more presses of the Home button bring up music controls that let you pause or skip without unlocking. It's almost iPod Shuffle-like. Now if only there were a way to assign star ratings without unlocking.
Many other day-to-day activities could benefit from this same kind of UI, in particular with the remote. You've got a lot of objects to consider or evaluate, and a limited number of actions for each one, including a default of "do nothing at all". Someone could play through a set of songs and give high / medium / low rating to each one, or trash it. A programmer could scroll through a list of bugs or functional specs, and for each one indicate "closed", "waiting for more information", "this does not apply to me", etc. That may be the way of the future, where carpal tunnel and hunched shoulders are just a distant memory.
Every now and then, I rediscover the infrared remote that goes with my iMac, and realize that for many mundane tasks, the remote does everything I need. (Mira lets me assign different actions for the remote button for specific applications. Candelair works around a Snow Leopard issue with Mira.)
For example, with a new album in a photo library, you might want to Next-Next-Next through each photo, and if one is particularly bad, trash it; if one is particularly good, mark it with a high rank or a coloured label; otherwise, leave it as-is and proceed to the next one. The up/down/left/right/play buttons on the remote can accomodate those actions comfortably. All the photo software offers keyboard shortcuts for these actions, that can be assigned to the remote buttons. So this brain-intensive task can be accomplished while sitting back and taking in the view on a large screen.
One thing had been bothering me about the UI for the iPod Touch. If I'm listening to music with the screen turned off, say in the car or the office, and I'm interrupted (want to stop the music suddenly) or annoyed (want to immediately skip to the next song), normally this requires turning on the screen (Home button or power button), and unlocking the iPod by swiping before the music controls are available. I should have realized Apple would bring the "single-action UI" to the rescue. Instead of unlocking the whole unit, once it is powered on in a locked state, 2 more presses of the Home button bring up music controls that let you pause or skip without unlocking. It's almost iPod Shuffle-like. Now if only there were a way to assign star ratings without unlocking.
Many other day-to-day activities could benefit from this same kind of UI, in particular with the remote. You've got a lot of objects to consider or evaluate, and a limited number of actions for each one, including a default of "do nothing at all". Someone could play through a set of songs and give high / medium / low rating to each one, or trash it. A programmer could scroll through a list of bugs or functional specs, and for each one indicate "closed", "waiting for more information", "this does not apply to me", etc. That may be the way of the future, where carpal tunnel and hunched shoulders are just a distant memory.
Subscribe to:
Posts (Atom)
